From 87b0fa598f0a01a07884deb83c14741f8021e1ff Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Tue, 27 Jul 2021 18:11:42 +0800
Subject: [PATCH] Merge branch 'master' of http://s16s652780.51mypc.cn:49896/r/zhba_enterprises

---
 src/components/Subjects/Choices/index.vue            |   89 
 src/const/constant.js                                |   10 
 src/views/resource/oss.vue                           |  760 ++-
 src/assets/css/_responsive.scss                      |   11 
 src/api/examapi/performance.js                       |   21 
 src/views/trainingRegistration/index.vue             |    5 
 src/views/dispatch/dispatchChildoperable.vue         |  149 
 src/components/Subjects/Judgement/index.vue          |   81 
 src/api/exam/knowledge.js                            |   18 
 src/api/exam/exam.js                                 |   84 
 src/api/examapi/examination.js                       |   39 
 src/views/resource/attach.vue                        |    2 
 src/views/securityGuard/data.js                      |  876 ++--
 src/api/exam/course.js                               |   57 
 src/assets/css/subject.scss                          |   81 
 src/views/system/dict.vue                            |  186 
 src/views/system/topmenu.vue                         |  629 +-
 src/api/exam/subjectCategory.js                      |   41 
 src/const/errorCode.js                               |   12 
 src/views/workreport/workreport.vue                  |    6 
 src/api/examapi/subject.js                           |   23 
 src/views/recruitmentManagement/index.vue            |    2 
 src/views/securityEquipment/gun.js                   |   11 
 src/config/iconList.js                               |   11 
 src/views/system/menu.vue                            |  755 +-
 src/views/securityUnit/data.js                       |   21 
 src/components/Subjects/PracticalOperation/index.vue |  190 
 src/views/desk/notice.vue                            |    2 
 src/views/authority/role.vue                         |    2 
 src/components/Tinymce/toolbar.js                    |    6 
 src/views/dispatch/dispatch.vue                      |    1 
 src/views/exam/subject.vue                           |  263 +
 src/views/singleperformance/index.vue                |  398 ++
 src/views/exam/startexam.vue                         |  388 +
 src/api/exam/subject.js                              |   74 
 src/components/Subjects/ShortAnswer/index.vue        |   73 
 src/views/system/client.vue                          |  594 +-
 src/views/exam/examination.vue                       |  478 ++
 src/views/applyexam/index.vue                        |  461 ++
 src/assets/css/style.scss                            | 1084 +++++
 src/assets/css/transition.scss                       |   12 
 package-lock.json                                    |   10 
 src/assets/css/_fonts.scss                           |    3 
 src/views/securityGuard/securityGuard.vue            |    5 
 src/views/system/user.vue                            |    2 
 src/components/Tinymce/components/editorImage.vue    |  103 
 src/views/securityEquipment/gun.vue                  |    3 
 src/store/modules/common.js                          |   10 
 src/views/workreport/data.js                         |  432 +-
 src/assets/css/_theme_color.scss                     |   29 
 src/components/Subjects/MultipleChoices/index.vue    |   99 
 src/views/exam/topicDetails.vue                      |  211 +
 src/views/startexam/index.vue                        |  663 +++
 src/views/exam/performance.vue                       |  398 ++
 src/api/exam/answer.js                               |  124 
 src/views/securityEquipment/car.vue                  |    3 
 src/views/system/dept.vue                            |    2 
 src/views/securityUnit/index.vue                     |    5 
 src/components/Tinymce/index.vue                     |  162 
 src/components/Tinymce/plugins.js                    |    7 
 src/api/applyexam/applyexam.js                       |  120 
 src/api/exam/examRecord.js                           |   58 
 src/styles/element-ui.scss                           |  141 
 src/views/system/dictbiz.vue                         |  654 +-
 src/views/securityEquipment/equipments.vue           |    3 
 src/config/env.js                                    |    2 
 src/views/exam/examSubjects.vue                      |  328 +
 src/assets/css/mixin.scss                            |   79 
 src/api/examapi/applyexam.js                         |   47 
 package.json                                         |    2 
 src/api/examapi/examSubjects.js                      |   37 
 71 files changed, 9,317 insertions(+), 2,431 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 65c8df5..ff99a2c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7471,6 +7471,11 @@
         "commander": "*"
       }
     },
+    "moment": {
+      "version": "2.29.1",
+      "resolved": "https://registry.nlark.com/moment/download/moment-2.29.1.tgz",
+      "integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M="
+    },
     "move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -11938,6 +11943,11 @@
       "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
       "dev": true
     },
+    "vue2-countdown": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npm.taobao.org/vue2-countdown/download/vue2-countdown-1.0.8.tgz",
+      "integrity": "sha1-4PILava62zPPmcjMPfUdLHfy7zU="
+    },
     "vuex": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz",
diff --git a/package.json b/package.json
index 8e8c6b3..4662c34 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
     "js-cookie": "^2.2.0",
     "js-md5": "^0.7.3",
     "mockjs": "^1.0.1-beta3",
+    "moment": "^2.29.1",
     "node-gyp": "^5.0.6",
     "nprogress": "^0.2.0",
     "portfinder": "^1.0.23",
@@ -29,6 +30,7 @@
     "vue-axios": "^2.1.2",
     "vue-i18n": "^8.7.0",
     "vue-router": "^3.0.1",
+    "vue2-countdown": "^1.0.8",
     "vuex": "^3.1.1"
   },
   "devDependencies": {
diff --git a/src/api/applyexam/applyexam.js b/src/api/applyexam/applyexam.js
new file mode 100644
index 0000000..14e597d
--- /dev/null
+++ b/src/api/applyexam/applyexam.js
@@ -0,0 +1,120 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params, deptId) => {
+  return request({
+    url: '/api/blade-user/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+      deptId,
+    }
+  })
+}
+
+export const remove = (ids) => {
+  return request({
+    url: '/api/blade-user/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
+
+export const add = (row) => {
+  return request({
+    url: '/api/blade-user/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const update = (row) => {
+  return request({
+    url: '/api/blade-user/update',
+    method: 'post',
+    data: row
+  })
+}
+
+export const updatePlatform = (userId, userType, userExt) => {
+  return request({
+    url: '/api/blade-user/update-platform',
+    method: 'post',
+    params: {
+      userId,
+      userType,
+      userExt,
+    }
+  })
+}
+
+export const getUser = (id) => {
+  return request({
+    url: '/api/blade-user/detail',
+    method: 'get',
+    params: {
+      id,
+    }
+  })
+}
+
+export const getUserPlatform = (id) => {
+  return request({
+    url: '/api/blade-user/platform-detail',
+    method: 'get',
+    params: {
+      id,
+    }
+  })
+}
+
+export const getUserInfo = () => {
+  return request({
+    url: '/api/blade-user/info',
+    method: 'get',
+  })
+}
+
+export const resetPassword = (userIds) => {
+  return request({
+    url: '/api/blade-user/reset-password',
+    method: 'post',
+    params: {
+      userIds,
+    }
+  })
+}
+
+export const updatePassword = (oldPassword, newPassword, newPassword1) => {
+  return request({
+    url: '/api/blade-user/update-password',
+    method: 'post',
+    params: {
+      oldPassword,
+      newPassword,
+      newPassword1,
+    }
+  })
+}
+
+export const updateInfo = (row) => {
+  return request({
+    url: '/api/blade-user/update-info',
+    method: 'post',
+    data: row
+  })
+}
+
+export const grant = (userIds, roleIds) => {
+  return request({
+    url: '/api/blade-user/grant',
+    method: 'post',
+    params: {
+      userIds,
+      roleIds,
+    }
+  })
+}
diff --git a/src/api/exam/answer.js b/src/api/exam/answer.js
new file mode 100644
index 0000000..42de680
--- /dev/null
+++ b/src/api/exam/answer.js
@@ -0,0 +1,124 @@
+import request from '@/router/axios'
+
+const baseAnswerUrl = '/api/exam/v1/answer/'
+
+export function fetchAnswerList(query) {
+  return request({
+    url: baseAnswerUrl + 'answerList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getAnswer(id) {
+  return request({
+    url: baseAnswerUrl + id,
+    method: 'get'
+  })
+}
+
+export function getAnswerInfo(id, query) {
+  return request({
+    url: baseAnswerUrl + id + '/info',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getAnswerListInfo(id, query) {
+  return request({
+    url: baseAnswerUrl + 'record/' + id + '/answerListInfo',
+    method: 'get',
+    params: query
+  })
+}
+
+export function addAnswer(obj) {
+  return request({
+    url: baseAnswerUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function putAnswer(obj) {
+  return request({
+    url: baseAnswerUrl,
+    method: 'put',
+    data: obj
+  })
+}
+
+export function delAnswer(id) {
+  return request({
+    url: baseAnswerUrl + id,
+    method: 'delete'
+  })
+}
+
+export function save(obj) {
+  return request({
+    url: baseAnswerUrl + 'save',
+    method: 'post',
+    data: obj
+  })
+}
+
+export const saveAndNext = (params) => {
+  return request({
+    url: '/api/examScore/saveExamScore',
+    method: 'post',
+    data: {
+      // "allGrade": 0,
+      "allScore": 200,
+      "candidateNo": params.securityId + '  ',
+      "company": params.company,
+      "examName": params.examName,
+      "examResultVOS": params.examResultVOS,
+      "examTime": params.examTime,
+      "examType": Number(params.examType),
+      "learnGrade": 0,
+      "papersId": Number(params.papersId),
+      "securityName": params.securityName
+    }
+  })
+}
+
+export function anonymousUserSaveAndNext(obj, nextType, nextSubjectId, nextSubjectType) {
+  let url = baseAnswerUrl + 'anonymousUser/saveAndNext?nextType=' + nextType
+  if (nextSubjectId !== undefined) {
+    url += '&nextSubjectId=' + nextSubjectId
+  }
+  if (nextSubjectType !== undefined) {
+    url += '&nextSubjectType=' + nextSubjectType
+  }
+  return request({
+    url: url,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function submit(obj) {
+  return request({
+    url: baseAnswerUrl + 'submit',
+    method: 'post',
+    data: obj
+  })
+}
+
+export function anonymousUserSubmit(obj) {
+  return request({
+    url: baseAnswerUrl + 'anonymousUser/submit',
+    method: 'post',
+    data: obj
+  })
+}
+
+export function anonymousUserSubmitAll(obj, examinationId, identifier) {
+  return request({
+    url: baseAnswerUrl + 'anonymousUser/submitAll/' + examinationId + '?identifier=' + identifier,
+    method: 'post',
+    data: obj
+  })
+}
diff --git a/src/api/exam/course.js b/src/api/exam/course.js
new file mode 100644
index 0000000..612c969
--- /dev/null
+++ b/src/api/exam/course.js
@@ -0,0 +1,57 @@
+import request from '@/router/axios'
+
+const baseCourseUrl = '/api/exam/v1/course/'
+
+export function courseList (query) {
+  return request({
+    url: baseCourseUrl + 'courseList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchCourseList (query) {
+  return request({
+    url: baseCourseUrl + 'courseList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getObj (id) {
+  return request({
+    url: baseCourseUrl + id,
+    method: 'get'
+  })
+}
+
+export function addObj (obj) {
+  return request({
+    url: baseCourseUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function putObj (obj) {
+  return request({
+    url: baseCourseUrl,
+    method: 'put',
+    data: obj
+  })
+}
+
+export function delObj (id) {
+  return request({
+    url: baseCourseUrl + id,
+    method: 'delete'
+  })
+}
+
+export function delAllObj (obj) {
+  return request({
+    url: baseCourseUrl + 'deleteAll',
+    method: 'post',
+    data: obj
+  })
+}
diff --git a/src/api/exam/exam.js b/src/api/exam/exam.js
new file mode 100644
index 0000000..b87bfe5
--- /dev/null
+++ b/src/api/exam/exam.js
@@ -0,0 +1,84 @@
+import request from '@/router/axios'
+
+const baseExaminationUrl = '/api/exam/v1/examination/'
+
+export function fetchList (query) {
+  return request({
+    url: baseExaminationUrl + 'examinationList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function fetchAllSubjectList (query) {
+  return request({
+    url: baseExaminationUrl + 'anonymousUser/allSubjectList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getObj (id, query) {
+  return request({
+    url: baseExaminationUrl + id,
+    method: 'get',
+    params: query
+  })
+}
+
+export function anonymousUserGetObj (id, query) {
+  return request({
+    url: baseExaminationUrl + 'anonymousUser/' + id,
+    method: 'get',
+    params: query
+  })
+}
+
+export const getSubjectIds = (param) => {
+  return request({
+    url: '/api/exampaper/queryPagerSubject/',
+    method: 'get',
+    params: {
+      ...param
+    }
+  })
+}
+
+export function anonymousUserGetSubjectIds (id, query) {
+  return request({
+    url: baseExaminationUrl + 'anonymousUser/' + id + '/subjectIds',
+    method: 'get',
+    params: query
+  })
+}
+
+export function addObj (obj) {
+  return request({
+    url: baseExaminationUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function putObj (obj) {
+  return request({
+    url: baseExaminationUrl,
+    method: 'put',
+    data: obj
+  })
+}
+
+export function delObj (id) {
+  return request({
+    url: baseExaminationUrl + id,
+    method: 'delete'
+  })
+}
+
+export function delAllObj (obj) {
+  return request({
+    url: baseExaminationUrl + 'deleteAll',
+    method: 'post',
+    data: obj
+  })
+}
diff --git a/src/api/exam/examRecord.js b/src/api/exam/examRecord.js
new file mode 100644
index 0000000..b1e407b
--- /dev/null
+++ b/src/api/exam/examRecord.js
@@ -0,0 +1,58 @@
+import request from '@/router/axios'
+
+const baseExamRecordUrl = '/api/exam/v1/examRecord/'
+
+export function fetchList (query) {
+  return request({
+    url: baseExamRecordUrl + 'examRecordList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getObj (id, query) {
+  return request({
+    url: baseExamRecordUrl + id,
+    method: 'get',
+    params: query
+  })
+}
+
+export function addObj (obj) {
+  return request({
+    url: baseExamRecordUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function start (obj) {
+  return request({
+    url: baseExamRecordUrl + 'start',
+    method: 'post',
+    data: obj
+  })
+}
+
+export function anonymousUserStart (obj) {
+  return request({
+    url: baseExamRecordUrl + 'anonymousUser/start',
+    method: 'post',
+    params: obj
+  })
+}
+
+export function getCurrentTime () {
+  return request({
+    url: '/api/exampaper/getdate',
+    method: 'get'
+  })
+}
+
+// 查询成绩详情
+export function examRecordDetails (id) {
+  return request({
+    url: baseExamRecordUrl + id + '/details',
+    method: 'get'
+  })
+}
diff --git a/src/api/exam/knowledge.js b/src/api/exam/knowledge.js
new file mode 100644
index 0000000..673b9ad
--- /dev/null
+++ b/src/api/exam/knowledge.js
@@ -0,0 +1,18 @@
+import request from '@/router/axios'
+
+const baseKnowledgeUrl = '/api/exam/v1/knowledge/'
+
+export function fetchKnowledgeList (query) {
+  return request({
+    url: baseKnowledgeUrl + 'knowledgeList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getObj (id) {
+  return request({
+    url: baseKnowledgeUrl + id,
+    method: 'get'
+  })
+}
diff --git a/src/api/exam/subject.js b/src/api/exam/subject.js
new file mode 100644
index 0000000..3eefe79
--- /dev/null
+++ b/src/api/exam/subject.js
@@ -0,0 +1,74 @@
+import request from '@/router/axios'
+
+const baseSubjectUrl = '/api/exam/v1/subject/'
+
+export function subjectList () {
+  return request({
+    url: baseSubjectUrl + 'subjectList',
+    method: 'get'
+  })
+}
+
+export function fetchSubjectList (query) {
+  return request({
+    url: baseSubjectUrl + 'subjectList',
+    method: 'get',
+    params: query
+  })
+}
+
+export function getObj (id, query) {
+  return request({
+    url: baseSubjectUrl + id,
+    method: 'get',
+    params: query
+  })
+}
+
+export function addSubject (obj) {
+  return request({
+    url: baseSubjectUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function putSubject (obj) {
+  return request({
+    url: baseSubjectUrl,
+    method: 'put',
+    data: obj
+  })
+}
+
+export function delSubject (id) {
+  return request({
+    url: baseSubjectUrl + id,
+    method: 'delete'
+  })
+}
+
+export function delAllSubject (obj) {
+  return request({
+    url: baseSubjectUrl + 'deleteAll',
+    method: 'post',
+    data: obj
+  })
+}
+
+export function getSubjectAnswer (obj) {
+  return request({
+    url: '/api/examSubjectChoices/details',
+    method: 'get',
+    params: obj
+  })
+}
+
+
+export function anonymousUserGetSubjectAnswer (obj) {
+  return request({
+    url: baseSubjectUrl + 'anonymousUser/subjectAnswer',
+    method: 'get',
+    params: obj
+  })
+}
diff --git a/src/api/exam/subjectCategory.js b/src/api/exam/subjectCategory.js
new file mode 100644
index 0000000..0c095e1
--- /dev/null
+++ b/src/api/exam/subjectCategory.js
@@ -0,0 +1,41 @@
+import request from '@/router/axios'
+
+const baseSubjectCategoryUrl = '/api/exam/v1/subjectCategory/'
+
+export function fetchTree (query) {
+  return request({
+    url: baseSubjectCategoryUrl + 'categories',
+    method: 'get',
+    params: query
+  })
+}
+
+export function addObj (obj) {
+  return request({
+    url: baseSubjectCategoryUrl,
+    method: 'post',
+    data: obj
+  })
+}
+
+export function getObj (id) {
+  return request({
+    url: baseSubjectCategoryUrl + id,
+    method: 'get'
+  })
+}
+
+export function delObj (id) {
+  return request({
+    url: baseSubjectCategoryUrl + id,
+    method: 'delete'
+  })
+}
+
+export function putObj (obj) {
+  return request({
+    url: baseSubjectCategoryUrl,
+    method: 'put',
+    data: obj
+  })
+}
diff --git a/src/api/examapi/applyexam.js b/src/api/examapi/applyexam.js
new file mode 100644
index 0000000..08c81f2
--- /dev/null
+++ b/src/api/examapi/applyexam.js
@@ -0,0 +1,47 @@
+import request from '@/router/axios';
+
+
+export const getApplyList = (current, size, params) => {
+  return request({
+    url: '/api/apply/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size
+    }
+  })
+}
+
+export const addApply = (row) => {
+  return request({
+    url: '/api/apply/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+
+
+export const remove = (ids) => {
+  return request({
+    url: '/api/apply/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
+
+
+
+
+export const getMenu = (id) => {
+  return request({
+    url: '/api/apply/detail',
+    method: 'get',
+    params: {
+      id,
+    }
+  })
+}
diff --git a/src/api/examapi/examSubjects.js b/src/api/examapi/examSubjects.js
new file mode 100644
index 0000000..36f863b
--- /dev/null
+++ b/src/api/examapi/examSubjects.js
@@ -0,0 +1,37 @@
+import request from '@/router/axios';
+
+export const getPaperList = (current, size, params) => {
+  return request({
+    url: '/api/examSubjectChoices/getEexPaperChoices',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size
+    }
+  })
+}
+
+
+export const updatePaper = (row) => {
+  return request({
+    url: '/api/examSubjectChoices/updateChoicesValue',
+    method: 'post',
+    params: {
+      ...row
+    }
+  })
+}
+
+
+
+
+export const remove = (params) => {
+  return request({
+    url: '/api/exampaper/UnbindSubject',
+    method: 'get',
+    params: {
+      ...params
+    }
+  })
+}
diff --git a/src/api/examapi/examination.js b/src/api/examapi/examination.js
new file mode 100644
index 0000000..c1fe666
--- /dev/null
+++ b/src/api/examapi/examination.js
@@ -0,0 +1,39 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/exampaper/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size
+    }
+  })
+}
+
+export const remove = (ids) => {
+  return request({
+    url: '/api/exampaper/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
+
+export const add = (row) => {
+  return request({
+    url: '/api/exampaper/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const update = (row) => {
+  return request({
+    url: '/api/exampaper/update',
+    method: 'post',
+    data: row
+  })
+}
diff --git a/src/api/examapi/performance.js b/src/api/examapi/performance.js
new file mode 100644
index 0000000..ba130f1
--- /dev/null
+++ b/src/api/examapi/performance.js
@@ -0,0 +1,21 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/examScore/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size
+    }
+  })
+}
+
+export const update = (row) => {
+  return request({
+    url: '/api/examScore/updateExamScore',
+    method: 'post',
+    data: row
+  })
+}
diff --git a/src/api/examapi/subject.js b/src/api/examapi/subject.js
new file mode 100644
index 0000000..29867db
--- /dev/null
+++ b/src/api/examapi/subject.js
@@ -0,0 +1,23 @@
+import request from '@/router/axios';
+
+export const getList = (current, size, params) => {
+  return request({
+    url: '/api/examSubjectChoices/page',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size
+    }
+  })
+}
+
+export const remove = (ids) => {
+  return request({
+    url: '/api/examSubjectChoices/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
diff --git a/src/assets/css/_fonts.scss b/src/assets/css/_fonts.scss
new file mode 100644
index 0000000..980c47f
--- /dev/null
+++ b/src/assets/css/_fonts.scss
@@ -0,0 +1,3 @@
+// Fonts
+$opensans-font: 'Open Sans', sans-serif;
+$raleway-font: 'Raleway', sans-serif;
diff --git a/src/assets/css/_responsive.scss b/src/assets/css/_responsive.scss
new file mode 100644
index 0000000..6cce9d1
--- /dev/null
+++ b/src/assets/css/_responsive.scss
@@ -0,0 +1,11 @@
+$breakpoint-xl: 'only screen and (min-width:1200px)';
+
+$breakpoint-lg: 'only screen and (min-width:992px) and (max-width:1199px)';
+
+$breakpoint-md: 'only screen and (min-width:768px) and (max-width:991px)';
+
+$breakpoint-sm: 'only screen and (min-width:576px) and (max-width:767px)';
+
+$breakpoint-xs: 'only screen and (max-width:767px)';
+
+$breakpoint-xs-landscape: 'only screen and (min-width:480px) and (max-width:767px)';
diff --git a/src/assets/css/_theme_color.scss b/src/assets/css/_theme_color.scss
new file mode 100644
index 0000000..3dae507
--- /dev/null
+++ b/src/assets/css/_theme_color.scss
@@ -0,0 +1,29 @@
+// Heading Color
+$heading-color: rgba(0, 0, 0, 0.8);
+
+// Text Color
+$text-color: #5a5a5a;
+
+// Default Background
+$bg-default: #3762f0;
+
+// Gray Background
+$bg-gray: #f7f7f7;
+
+// White Color
+$white-color: #ffffff;
+
+// Dark Color
+$dark-color: #1b1b1b;
+
+// Border Color
+$border-color: #ebebeb;
+
+// Hover Color
+$hover-color: #2c56df;
+
+// Footer Color
+$footer-color: #252525;
+
+// Border Color
+$border-color: #ebebeb;
diff --git a/src/assets/css/mixin.scss b/src/assets/css/mixin.scss
new file mode 100644
index 0000000..1593d5a
--- /dev/null
+++ b/src/assets/css/mixin.scss
@@ -0,0 +1,79 @@
+@mixin wh($w,$h:$w) {
+  width: $w;
+  height: $h;
+}
+
+@mixin trans-duration($time) {
+  -webkit-transition-duration: $time;
+  transition-duration: $time;
+}
+
+@mixin transition($value) {
+  -webkit-transition: $value;
+  transition: $value;
+}
+
+@mixin transform($value) {
+  -webkit-transform: $value;
+  transform: $value;
+}
+
+@mixin animation($value) {
+  -webkit-animation: $value;
+  animation: $value;
+}
+
+@mixin flex-direction($value) {
+  -webkit-box-orient: horizontal;
+  -webkit-box-direction: reverse;
+  -ms-flex-direction: $value;
+  flex-direction: $value;
+}
+
+@mixin align-items($value) {
+  -webkit-box-align: $value;
+  -ms-flex-align: $value;
+  -ms-grid-row-align: $value;
+  align-items: $value;
+}
+
+@mixin display-flex($value) {
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: $value;
+}
+
+@mixin justify-content-between {
+  -webkit-box-pack: justify;
+  -ms-flex-pack: justify;
+  justify-content: space-between;
+}
+
+@mixin justify-content($value) {
+  -webkit-box-pack: center;
+  -ms-flex-pack: center;
+  justify-content: center;
+}
+
+@mixin justify-content-end {
+  -webkit-box-pack: end;
+  -ms-flex-pack: end;
+  justify-content: flex-end;
+}
+
+@mixin flex($value) {
+  -webkit-box-flex: 0;
+  -ms-flex: $value;
+  flex: $value;
+}
+
+@mixin flex-wrap($value) {
+  -ms-flex-wrap: $value;
+  flex-wrap: $value;
+}
+
+@mixin bg-gradients {
+  background: #0d104d;
+  background: -webkit-linear-gradient(to right, #0d104d, #28408b);
+  background: linear-gradient(to right, #0d104d, #28408b);
+}
diff --git a/src/assets/css/style.scss b/src/assets/css/style.scss
new file mode 100644
index 0000000..f6e8340
--- /dev/null
+++ b/src/assets/css/style.scss
@@ -0,0 +1,1084 @@
+@import 'theme_color';
+@import '_fonts';
+@import 'mixin';
+@import 'responsive';
+@import 'transition';
+
+* {
+  margin: 0;
+  padding: 0;
+}
+
+body {
+  font-family: $opensans-font;
+  font-size: 14px;
+  font-weight: 400;
+  margin: 0;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  color: $heading-color;
+  line-height: 1.3;
+  font-weight: 700;
+
+}
+
+p {
+  font-family: $raleway-font;
+  color: $text-color;
+  font-size: 14px;
+  line-height: 1.8;
+  font-weight: 400;
+}
+
+a,
+a:hover,
+a:focus {
+  @include trans-duration(500ms);
+  text-decoration: none;
+  outline: 0 solid transparent;
+  color: $heading-color;
+  font-weight: 600;
+  font-size: 14px;
+}
+
+ul,
+ol {
+  margin: 0;
+  li {
+    list-style: none;
+  }
+}
+
+img {
+  height: auto;
+  max-width: 100%;
+}
+
+.padding-80-0 {
+  padding-top: 80px;
+  padding-bottom: 0;
+}
+
+.mb-80 {
+  margin-bottom: 80px;
+}
+
+.mb-12 {
+  margin-bottom: 12px;
+}
+
+.mr-100 {
+  margin-right: 100px;
+}
+
+.ml-100 {
+  margin-left: 100px;
+}
+
+.padding-80 {
+  padding-top: 80px;
+  padding-bottom: 80px;
+}
+
+.mb-30 {
+  margin-bottom: 30px;
+}
+.w-100 {
+  width: 100%;
+}
+.justify-content-center {
+  @include justify-content(center);
+}
+
+.align-items-center {
+  @include align-items(center)
+}
+
+.d-flex {
+  display: -ms-flexbox;
+  display: flex;
+}
+
+.text-center {
+  text-align: center;
+}
+
+.fade-enter-active, .fade-leave-active {
+  transition: opacity .5s;
+}
+.fade-enter, .fade-leave-to {
+  opacity: 0;
+}
+
+.justify-content-between {
+  @include justify-content-between
+}
+
+.header-area.vue-fixed-header--isFixed {
+  position: fixed;
+  left: 0;
+  top: 0;
+  width: 100vw;
+}
+
+.header-area {
+  z-index: 1500 !important;
+  background-color: $white-color;
+  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
+  .clever-main-menu {
+    position: relative;
+    width: 100%;
+    height: 70px;
+    .classy-navbar {
+      padding: .5em 2em;
+      display: flex;
+      align-items: center;
+      justify-content: space-between!important;
+      .nav-brand {
+        color: #565656;
+        display: inline-block;
+        margin-right: 30px;
+        font-size: 30px;
+        font-weight: 600;
+      }
+      .nav-brand:focus, .classy-navbar .nav-brand:hover {
+        font-size: 26px;
+        font-weight: 500;
+      }
+    }
+    .classynav {
+      .el-menu--horizontal {
+        border-bottom: none;
+        .el-menu-item {
+          padding: 0 12px;
+          display: block;
+          border-bottom: none;
+        }
+        .el-submenu {
+          .el-submenu__title {
+            border-bottom: none !important;
+          }
+        }
+      }
+    }
+    .classynav ul li a {
+      color: rgba(0, 0, 0, 0.45);
+      font-weight: 600;
+      @media #{$breakpoint-lg} {
+        padding: 0 8px;
+      }
+      &:hover,
+      &:focus {
+        color: $heading-color;
+      }
+    }
+    .classy-nav-container a {
+      @include trans-duration(500ms);
+      color: #232323;
+      display: inline-block;
+      text-decoration: none;
+      outline: 0;
+    }
+    .search-area {
+      position: relative;
+      width: 230px;
+      height: 40px;
+      margin: 0 50px;
+      @media #{$breakpoint-lg} {
+        width: 170px;
+        margin: 0 15px;
+      }
+      @media #{$breakpoint-md} {
+        margin: 15px auto;
+      }
+      @media #{$breakpoint-xs} {
+        margin: 15px auto;
+      }
+      input {
+        width: 100%;
+        height: 40px;
+        border-radius: 6px;
+        border: 1px solid $border-color;
+        padding: 0 15px 0 50px;
+        font-size: 14px;
+        color: rgba(0, 0, 0, 0.35);
+        font-weight: 600;
+        @include trans-duration(500ms);
+        &:focus {
+          border: 1px solid rgba(0, 0, 0, 0.5);
+        }
+      }
+    }
+  }
+}
+.classy-nav-container * {
+  box-sizing: border-box;
+}
+
+.classy-navbar-toggler {
+  border: none;
+  background-color: transparent;
+  cursor: pointer;
+  display: none;
+}
+
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+  .clever-main-menu .classynav ul li a {
+    padding: 0 8px;
+  }
+}
+
+.clever-main-menu .classynav ul li a:hover, .clever-main-menu .classynav ul li a:focus {
+  color: rgba(0, 0, 0, 0.8);
+}
+
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+  .clever-main-menu .search-area form {
+    width: 170px;
+    margin: 0 15px;
+  }
+}
+
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+  .clever-main-menu .search-area form {
+    margin: 15px auto;
+  }
+}
+
+@media only screen and (max-width: 767px) {
+  .clever-main-menu .search-area form {
+    margin: 15px auto;
+  }
+}
+
+.classycloseIcon, .dd-trigger {
+  position: absolute;
+  display: none;
+}
+
+.breakpoint-off .classynav {
+  display: -webkit-box;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: center;
+  align-items: center;
+}
+
+.breakpoint-off .classynav, .classy-navbar {
+  -webkit-box-align: center;
+  -ms-grid-row-align: center;
+}
+
+.register-login-area {
+  position: relative;
+  z-index: 1;
+}
+
+.btn:not(:disabled):not(.disabled) {
+  cursor: pointer;
+}
+
+.register-login-area a {
+  position: relative;
+  display: inline-block;
+  padding: 0 20px;
+  height: 40px;
+  font-weight: 600;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  font-size: 14px;
+  color: #3762f0;
+  line-height: 40px;
+}
+
+.classy-nav-container a, .classy-nav-container a:focus, .classy-nav-container a:hover {
+  @include trans-duration(500ms);
+  text-decoration: none;
+  outline: 0;
+  font-size: 14px;
+  font-weight: 400;
+}
+
+.btn:not(:disabled):not(.disabled).active, .btn:not(:disabled):not(.disabled):active {
+  background-image: none;
+}
+
+.btn:not(:disabled):not(.disabled) {
+  cursor: pointer;
+}
+
+.register-login-area a.active, .register-login-area a:hover, .register-login-area a:focus {
+  background-color: #d7e0fc;
+  font-weight: 600;
+  color: #3762f0;
+}
+
+.register-login-area a {
+  position: relative;
+  display: inline-block;
+  padding: 0 20px;
+  height: 40px;
+  font-weight: 600;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  font-size: 14px;
+  color: #3762f0;
+  line-height: 40px;
+}
+
+.classy-nav-container a, .classy-nav-container a:focus, .classy-nav-container a:hover {
+  @include trans-duration(500ms);
+  text-decoration: none;
+  outline: 0;
+  font-size: 14px;
+  font-weight: 400;
+}
+
+.el-menu-link {
+  color: rgba(0, 0, 0, 0.45)!important;
+  font-size: 14px;
+  padding: 0 20px;
+  cursor: pointer;
+}
+
+/* 首页 */
+.hero-area {
+  position: relative;
+  z-index: 2;
+  width: 100%;
+  height: 325px;
+  align-items: center!important;
+  background-image: url("/static/img/bg-img/bg1.jpg");
+  background-attachment: fixed;
+  background-position: center center;
+  background-size: cover;
+  background-repeat: no-repeat;
+  ::after {
+    background-color: rgba(0, 0, 0, 0.1);
+    position: absolute;
+    z-index: -1;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    content: "";
+  }
+  .hero-content {
+    text-align: center;
+    h2 {
+      font-size: 40px;
+      margin-bottom: 10px;
+      font-weight: 700;
+      color: $white-color;
+    }
+    h4 {
+      font-size: 22px;
+      margin-bottom: 20px;
+      font-weight: 500;
+      color: $white-color;
+    }
+  }
+}
+.btn:not(:disabled):not(.disabled) {
+  cursor: pointer;
+}
+.clever-btn {
+  @include trans-duration(300ms);
+  display: inline-block;
+  min-width: 160px;
+  height: 40px;
+  background-color: #3762f0;
+  font-weight: 600;
+  text-transform: uppercase;
+  letter-spacing: 1px;
+  font-size: 14px;
+  color: $white-color;
+  border: 1px solid transparent;
+  border-radius: 6px;
+  padding: 0 30px;
+  line-height: 40px;
+  text-align: center;
+}
+.single-cool-facts-area {
+  text-align: center;
+  position: relative;
+  z-index: 1;
+  padding: 30px;
+  border: 1px solid #ebebeb;
+  border-radius: 6px;
+  margin-bottom: 80px !important;
+  cursor: pointer;
+}
+.popular-courses-area {
+  position: relative;
+  background-repeat: repeat;
+  background-image: url(/static/img/core-img/texture.png);
+  height: 600px;
+}
+
+.section-heading {
+  position: relative;
+  z-index: 1;
+  margin-bottom: 70px;
+  text-align: center;
+  h3 {
+    font-size: 30px;
+    margin-bottom: 0;
+    @media #{$breakpoint-xs} {
+      font-size: 24px;
+    }
+  }
+  &.text-left {
+    text-align: left !important;
+  }
+  &.white {
+    h3 {
+      color: $white-color;
+    }
+  }
+}
+
+.single-popular-course {
+  position: relative;
+  z-index: 1;
+  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
+  border-radius: 6px;
+  background-color: $white-color;
+  cursor: pointer;
+  img {
+    display: block;
+    width: 100%;
+    border-radius: 6px 6px 0 0;
+  }
+  .course-content {
+    padding: 25px;
+    h4 {
+      margin-bottom: 5px;
+    }
+    .meta {
+      margin-bottom: 15px;
+      span {
+        color: rgba(0, 0, 0, 0.4);
+        font-size: 5px;
+        margin-right: 10px;
+      }
+      a {
+        color: rgba(0, 0, 0, 0.4);
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        margin-right: 10px;
+        &:hover {
+          color: #000;
+        }
+      }
+    }
+    p {
+      margin-bottom: 0;
+    }
+  }
+  .seat-rating-fee {
+    display: inline-flex;
+    width: 100%;
+    height: 40px;
+    background-color: $bg-gray;
+    border-radius: 0 0 6px 6px;
+    .seat-rating {
+      font-size: 12px;
+      color: rgba(0, 0, 0, 0.3);
+      font-weight: 600;
+      height: 100%;
+      align-items: center;
+      div {
+        display: inline-block;
+        padding: 0 20px;
+        border-right: 1px solid $border-color;
+        height: 100%;
+        line-height: 40px;
+      }
+      i {
+        font-size: 13px;
+        color: rgba(0, 0, 0, 0.3);
+      }
+    }
+    .course-fee {
+      a {
+        display: inline-block;
+        width: 70px;
+        height: 40px;
+        border-radius: 0 0 6px 0;
+        background-color: #e3d21b;
+        text-align: center;
+        line-height: 40px;
+        font-size: 12px;
+        font-weight: 700;
+        text-transform: uppercase;
+        color: $white-color;
+        letter-spacing: 0.75px;
+        &.free {
+          background-color: $bg-default;
+        }
+      }
+    }
+  }
+}
+
+.single-blog-area {
+  position: relative;
+  z-index: 1;
+  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
+  border-radius: 6px;
+  cursor: pointer;
+  img {
+    display: block;
+    width: 100%;
+    border-radius: 6px 6px 0 0;
+  }
+  .blog-content {
+    padding: 25px;
+    .blog-headline {
+      display: block;
+      h4 {
+        margin-bottom: 5px;
+        margin-left: -1px;
+        @include trans-duration(500ms);
+        &:hover,
+        &:focus {
+          color: $hover-color;
+        }
+      }
+    }
+    .meta {
+      margin-bottom: 15px;
+      span {
+        color: rgba(0, 0, 0, 0.4);
+        font-size: 5px;
+        margin-right: 10px;
+      }
+      a {
+        color: rgba(0, 0, 0, 0.4);
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        margin-right: 10px;
+        @media #{$breakpoint-xs} {
+          font-size: 12px;
+        }
+        &:hover {
+          color: #000;
+        }
+      }
+    }
+    p {
+      margin-bottom: 0;
+    }
+  }
+}
+
+/* 返回顶部 */
+.go-top-box {
+  background-color: $white-color;
+  position: fixed;
+  right: 50px;
+  bottom: 150px;
+  width: 40px;
+  height: 40px;
+  border-radius: 20px;
+  cursor: pointer;
+  transition: .3s;
+  box-shadow: 0 0 6px rgba(0,0,0,.12);
+  z-index: 5;
+}
+.top-icon {
+  color: #409eff;
+  display: block !important;
+  line-height: 40px !important;
+  text-align: center;
+  font-size: 18px;
+}
+
+.content-container {
+  margin-top: 2rem;
+  margin-left: 100px;
+  margin-right: 100px;
+}
+
+
+.single-course-intro {
+  position: relative;
+  z-index: 1;
+  width: 100%;
+  height: 350px;
+  .single-course-intro-content {
+    width: 425px;
+    height: auto;
+    padding: 30px;
+    background-color: $white-color;
+    border-radius: 6px;
+    @media #{$breakpoint-xs} {
+      width: 280px;
+    }
+    .ratings {
+      margin-bottom: 20px;
+      i {
+        color: #e3d21b;
+        font-size: 13px;
+        padding: 0 3px;
+        display: inline-block;
+      }
+    }
+    h3 {
+      font-size: 30px;
+      margin-bottom: 10px;
+      @media #{$breakpoint-xs} {
+        font-size: 24px;
+      }
+    }
+    .meta {
+      margin-bottom: 30px;
+      span {
+        color: rgba(0, 0, 0, 0.4);
+        font-size: 5px;
+        margin-right: 10px;
+      }
+      a {
+        color: rgba(0, 0, 0, 0.4);
+        display: inline-block;
+        font-size: 14px;
+        font-weight: 400;
+        margin-right: 10px;
+        &:hover {
+          color: #000;
+        }
+      }
+    }
+    .price {
+      font-size: 12px;
+      text-transform: uppercase;
+      color: $bg-default;
+      letter-spacing: 0.75px;
+      font-weight: 700;
+    }
+  }
+}
+
+.clever-description {
+  position: relative;
+  z-index: 1;
+  .about-course {
+    padding: 40px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+    h4 {
+      margin-bottom: 20px;
+      display: block;
+    }
+    p {
+      font-size: 16px;
+      line-height: 1.9;
+      &:last-child {
+        margin-bottom: 0;
+      }
+    }
+    @media #{$breakpoint-xs} {
+      padding: 30px;
+    }
+  }
+  .all-instructors {
+    padding: 40px 40px 10px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+    @media #{$breakpoint-xs} {
+      padding: 30px 30px 0;
+    }
+    h4 {
+      margin-bottom: 25px;
+      display: block;
+    }
+    .single-instructor {
+      position: relative;
+      z-index: 1;
+      background-color: $bg-gray;
+      border-radius: 6px;
+      .instructor-thumb {
+        @include flex(0 0 80px);
+        width: 80px;
+        max-width: 80px;
+        height: 80px;
+      }
+      .instructor-info {
+        padding-left: 25px;
+        h5 {
+          font-size: 18px;
+          margin-bottom: 5px;
+          @media #{$breakpoint-xs} {
+            font-size: 14px;
+          }
+        }
+        span {
+          font-weight: 400;
+          color: rgba(0, 0, 0, 0.4);
+          font-size: 14px;
+        }
+      }
+    }
+  }
+  .clever-faqs {
+    padding: 40px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+    h4 {
+      margin-bottom: 25px;
+      display: block;
+    }
+    @media #{$breakpoint-xs} {
+      padding: 30px;
+    }
+  }
+}
+
+.about-curriculum {
+  padding: 40px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  h4 {
+    margin-bottom: 20px;
+    display: block;
+  }
+  p {
+    font-size: 16px;
+    line-height: 1.9;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+  @media #{$breakpoint-xs} {
+    padding: 30px;
+  }
+}
+.curriculum-level {
+  padding: 40px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  h4 {
+    margin-bottom: 20px;
+    display: block;
+  }
+  h5 {
+    color: rgba(0, 0, 0, 0.6);
+    font-size: 18px;
+  }
+  .curriculum-list {
+    li {
+      display: block;
+      margin-bottom: 10px;
+      font-family: $raleway-font;
+      font-size: 14px;
+      font-weight: 400;
+      color: rgba(0, 0, 0, 0.5);
+      &:last-child {
+        margin-bottom: 0;
+      }
+      i {
+        color: #e3d21b;
+        margin-right: 5px;
+        display: inline-block;
+      }
+      ul {
+        display: block;
+        margin-top: 10px;
+        padding-left: 25px;
+        li {
+          margin-bottom: 0;
+          @include display-flex(flex);
+          @include justify-content-between;
+          padding: 10px 0;
+          border-bottom: 1px solid $border-color;
+          span {
+            span {
+              text-decoration: underline;
+            }
+          }
+        }
+      }
+    }
+  }
+  @media #{$breakpoint-xs} {
+    padding: 30px;
+  }
+}
+
+.about-review {
+  padding: 40px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  h4 {
+    margin-bottom: 20px;
+    display: block;
+  }
+  p {
+    font-size: 16px;
+    line-height: 1.9;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+  @media #{$breakpoint-xs} {
+    padding: 30px;
+  }
+}
+.clever-ratings {
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  @media #{$breakpoint-xs} {
+    @include flex-wrap(wrap);
+  }
+  .total-ratings {
+    @include flex(0 0 235px);
+    min-width: 235px;
+    width: 235px;
+    border-right: 1px solid $border-color;
+    height: 250px;
+    @media #{$breakpoint-xs} {
+      @include flex(0 0 100%);
+      min-width: 100%;
+      width: 100%;
+      border-right: none;
+      border-bottom: 1px solid $border-color;
+    }
+    h2 {
+      font-size: 60px;
+      margin-bottom: 5px;
+    }
+    .ratings-- {
+      margin-bottom: 10px;
+      i {
+        font-size: 18px;
+        display: inline-block;
+        padding: 0 5px;
+        color: #e3d21b;
+      }
+    }
+    span {
+      font-size: 12px;
+      color: rgba(0, 0, 0, 0.3);
+    }
+  }
+  .rating-viewer {
+    padding: 50px 40px 35px;
+    @media #{$breakpoint-xs} {
+      padding: 40px 30px 25px;
+    }
+    span {
+      color: rgba(0, 0, 0, 0.3);
+      font-size: 12px;
+      text-transform: uppercase;
+      padding-right: 15px;
+      @media #{$breakpoint-lg} {
+        padding-right: 5px;
+        font-size: 11px;
+      }
+      @media #{$breakpoint-xs} {
+        padding-right: 5px;
+        font-size: 11px;
+      }
+    }
+    .progress {
+      width: 300px;
+      margin-right: 15px;
+      height: 10px;
+      border-radius: 0;
+      background-color: #f1f1f1;
+      @media #{$breakpoint-lg} {
+        width: 200px;
+      }
+      @media #{$breakpoint-md} {
+        width: 140px;
+      }
+      @media #{$breakpoint-xs} {
+        width: 140px;
+      }
+      .progress-bar {
+        background-color: #b3b3b3;
+      }
+    }
+  }
+  .single-review {
+    padding: 40px;
+    box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+    @media #{$breakpoint-xs} {
+      padding: 30px;
+    }
+    p {
+      margin-bottom: 0;
+    }
+    .review-admin {
+      .thumb {
+        @include flex(0 0 40px);
+        max-width: 40px;
+        width: 40px;
+      }
+      .text {
+        padding-left: 15px;
+        h6 {
+          font-size: 14px;
+          margin-bottom: 0;
+        }
+        span {
+          font-size: 12px;
+          color: rgba(0, 0, 0, 0.4);
+        }
+      }
+    }
+    .ratings {
+      i {
+        font-size: 14px;
+        display: inline-block;
+        padding: 0 3px;
+        color: #e3d21b;
+      }
+    }
+  }
+}
+
+.about-members {
+  padding: 40px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  @media #{$breakpoint-xs} {
+    padding: 30px;
+  }
+  h4 {
+    margin-bottom: 20px;
+    display: block;
+  }
+  p {
+    font-size: 16px;
+    line-height: 1.9;
+    &:last-child {
+      margin-bottom: 0;
+    }
+  }
+}
+.all-instructors {
+  padding: 40px 40px 10px;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  @media #{$breakpoint-xs} {
+    padding: 30px 30px 0;
+  }
+  h4 {
+    margin-bottom: 25px;
+    display: block;
+  }
+  .single-instructor {
+    position: relative;
+    z-index: 1;
+    background-color: $bg-gray;
+    border-radius: 6px;
+    .instructor-thumb {
+      @include flex(0 0 80px);
+      width: 80px;
+      max-width: 80px;
+      height: 80px;
+    }
+    .instructor-info {
+      padding-left: 25px;
+      h5 {
+        font-size: 18px;
+        margin-bottom: 5px;
+        @media #{$breakpoint-xs} {
+          font-size: 14px;
+        }
+      }
+      span {
+        font-weight: 400;
+        color: rgba(0, 0, 0, 0.4);
+        font-size: 14px;
+      }
+    }
+  }
+}
+
+.sidebar-widget {
+  position: relative;
+  z-index: 1;
+  padding: 35px 30px;
+  border: 1px solid $border-color;
+  border-bottom: none;
+  &:last-child {
+    border-bottom: 1px solid $border-color;
+  }
+  h4 {
+    margin-bottom: 20px;
+    font-size: 24px;
+    display: block;
+  }
+  .features-list {
+    li {
+      @include display-flex(flex);
+      @include justify-content-between;
+      margin-bottom: 5px;
+      h6 {
+        color: rgba(0, 0, 0, 0.3);
+        font-size: 14px;
+        @media #{$breakpoint-xs} {
+          font-size: 14px;
+        }
+        i {
+          margin-right: 10px;
+        }
+      }
+    }
+  }
+  .single--courses {
+    position: relative;
+    z-index: 1;
+    margin-bottom: 20px;
+    &:last-child {
+      margin-bottom: 0;
+    }
+    .thumb {
+      @include flex(0 0 80px);
+      width: 80px;
+      max-width: 80px;
+      height: 50px;
+      border-radius: 6px;
+      cursor: pointer;
+      img {
+        border-radius: 6px;
+      }
+    }
+    .content {
+      padding-left: 20px;
+      h5 {
+        font-size: 18px;
+        margin-bottom: 5px;
+        color: rgba(0, 0, 0, 0.35);
+        @media #{$breakpoint-xs} {
+          font-size: 14px;
+        }
+      }
+      h6 {
+        font-size: 12px;
+        color: #e3d21b;
+        margin-bottom: 0;
+      }
+    }
+  }
+}
+
+.single-course-content {
+  .el-tabs__nav {
+    margin-bottom: 20px;
+  }
+  .el-tabs__active-bar {
+    height: 0!important;
+  }
+  .el-tabs__nav-wrap::after {
+    height: 0;
+  }
+  .el-tab-pane {
+    margin: 20px;
+  }
+  .el-tabs__header {
+    margin-left: 30px;
+  }
+}
diff --git a/src/assets/css/subject.scss b/src/assets/css/subject.scss
new file mode 100644
index 0000000..caa2d53
--- /dev/null
+++ b/src/assets/css/subject.scss
@@ -0,0 +1,81 @@
+.subject-exam-title{
+  font-size: 18px;
+  line-height: 25px;
+  padding: 18px 20px;
+  border-bottom: 1px solid #DEDEDE;
+  margin-bottom: 12px;
+}
+.subject {
+  padding-left: 30px;
+  padding-right: 75px;
+}
+.subject-content{
+  margin-top: 18px;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  font-weight: 300;
+  background: #fff;
+  z-index: 1;
+  position: relative;
+}
+/* 题目 */
+.subject-title {
+  font-size: 18px;
+  line-height: 22px;
+  .subject-title-number {
+    display: inline-block;
+    line-height: 22px;
+  }
+  .subject-title-content {
+    // display: inline-block;
+  }
+}
+.subject-options {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  > li {
+    position: relative;
+    font-size: 24px;
+    .toggle {
+      opacity: 0;
+      text-align: center;
+      width: 35px;
+      /* auto, since non-WebKit browsers doesn't support input styling */
+      height: auto;
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      margin: auto 0;
+      border: none;
+      /* Mobile Safari */
+      -webkit-appearance: none;
+      appearance: none;
+    }
+    .toggle+label {
+      background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
+      background-repeat: no-repeat;
+      background-position: center left;
+      background-size: 30px;
+    }
+    .toggle:checked+label {
+      background-size: 30px;
+      background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
+    }
+    label {
+      word-break: break-all;
+      padding: 10px 10px 10px 45px;
+      display: block;
+      line-height: 1.0;
+      transition: color 0.4s;
+    }
+    /* 选项名称 */
+    .subject-option-prefix {
+      font-size: 16px;
+      display: inline-block
+    }
+  }
+}
+.subject-answer {
+  padding: 16px;
+}
diff --git a/src/assets/css/transition.scss b/src/assets/css/transition.scss
new file mode 100644
index 0000000..d37186a
--- /dev/null
+++ b/src/assets/css/transition.scss
@@ -0,0 +1,12 @@
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all .5s;
+}
+.fade-transform-enter {
+  opacity: 0;
+  transform: translateY(30px);
+}
+.fade-transform-leave-to {
+  opacity: 0;
+  transform: translateY(30px);
+}
diff --git a/src/components/Subjects/Choices/index.vue b/src/components/Subjects/Choices/index.vue
new file mode 100644
index 0000000..2297745
--- /dev/null
+++ b/src/components/Subjects/Choices/index.vue
@@ -0,0 +1,89 @@
+<template>
+    <div>
+        <div class="subject-content">
+            <div class="subject-title">
+                {{ index }}
+                <span class="subject-title-content"
+                      v-html="subjectInfo.subjectName" />
+                <span class="subject-title-content">
+                    (&nbsp;单选题&nbsp;<span v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;{{subjectInfo.score}}分&nbsp;</span>)
+                </span>
+            </div>
+
+            <ul class="subject-options"
+                v-for="option in options"
+                :key="option.id">
+                <li class="subject-option">
+                    <input class="toggle"
+                           type="checkbox"
+                           :checked="userAnswer === option.optionName"
+                           :id="'option' + option.id"
+                           @change="toggleOption(option)">
+                    <label :for="'option' + option.id">
+                        <span class="subject-option-prefix">{{ option.optionName + '.' }}&nbsp;</span>
+                        <span v-html="option.optionContent"
+                              class="subject-option-prefix" />
+                    </label>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'Choices',
+    data () {
+        return {
+            subjectCount: 0,
+            subjectInfo: {
+                subjectName: '',
+                score: 0
+            },
+            options: [],
+            userAnswer: '',
+            index: ''
+        }
+    },
+    methods: {
+        getAnswer () {
+            return this.userAnswer
+        },
+        setAnswer (answer) {
+            this.userAnswer = answer
+        },
+        setSubjectInfo (subject, subjectCount, index) {
+            this.subjectCount = subjectCount
+            this.subjectInfo = subject
+            if (subject.hasOwnProperty('examSubjectOptions')) {
+                this.options = subject.examSubjectOptions
+
+                console.log(this.options)
+            }
+            if (subject.hasOwnProperty('answer')) {
+                console.log(subject.answer);
+                this.setAnswer(subject.answer)
+            }
+            this.index = index + '.'
+
+            console.log(subject, subjectCount, index, this.options, 5656565656)
+        },
+        getSubjectInfo () {
+            this.subjectInfo.options = this.options
+            return this.subjectInfo
+        },
+        // 选中选项
+        toggleOption (option) {
+            this.userAnswer = option.optionName
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../../assets/css/subject.scss';
+.subject-options > li label {
+    height: 36px;
+    line-height: 28px !important;
+}
+</style>
diff --git a/src/components/Subjects/Judgement/index.vue b/src/components/Subjects/Judgement/index.vue
new file mode 100644
index 0000000..f1cae2f
--- /dev/null
+++ b/src/components/Subjects/Judgement/index.vue
@@ -0,0 +1,81 @@
+<template>
+    <div>
+        <div class="subject-content">
+            <div class="subject-title">
+                {{ index }}
+                <span class="subject-title-content"
+                      v-html="subjectInfo.subjectName" />
+                <span class="subject-title-content">
+                    (&nbsp;判断题&nbsp;<span v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;{{subjectInfo.score}}分&nbsp;</span>)
+                </span>
+            </div>
+            <ul class="subject-options"
+                v-for="option in options"
+                :key="option.id">
+                <li class="subject-option">
+                    <input class="toggle"
+                           type="checkbox"
+                           :checked="userAnswer === option.optionName"
+                           :id="'option' + option.id"
+                           @change="toggleOption(option)">
+                    <label :for="'option' + option.id">
+                        <span class="subject-option-prefix">{{ option.optionName }}&nbsp;</span>
+                    </label>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'Judgement',
+    data () {
+        return {
+            subjectCount: 0,
+            subjectInfo: {
+                subjectName: '',
+                score: 0
+            },
+            options: [
+                { id: 1, optionName: '正确' },
+                { id: 2, optionName: '错误' }
+            ],
+            userAnswer: '',
+            index: ''
+        }
+    },
+    methods: {
+        getAnswer () {
+            return this.userAnswer
+        },
+        setAnswer (answer) {
+            this.userAnswer = answer
+        },
+        setSubjectInfo (subject, subjectCount, index) {
+            this.subjectCount = subjectCount
+            this.subjectInfo = subject
+            if (subject.hasOwnProperty('answer')) {
+                this.setAnswer(subject.answer)
+            }
+            this.index = index + '.'
+        },
+        getSubjectInfo () {
+            this.subjectInfo.options = this.options
+            return this.subjectInfo
+        },
+        // 选中选项
+        toggleOption (option) {
+            this.userAnswer = option.optionName
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../../assets/css/subject.scss';
+.subject-options > li label {
+    height: 36px;
+    line-height: 28px !important;
+}
+</style>
diff --git a/src/components/Subjects/MultipleChoices/index.vue b/src/components/Subjects/MultipleChoices/index.vue
new file mode 100644
index 0000000..91975ba
--- /dev/null
+++ b/src/components/Subjects/MultipleChoices/index.vue
@@ -0,0 +1,99 @@
+<template>
+    <div>
+        <div class="subject-content">
+            <div class="subject-title">
+                {{ index }}
+                <span class="subject-title-content"
+                      v-html="subjectInfo.subjectName" />
+                <span class="subject-title-content">
+                    (&nbsp;多选题&nbsp;<span v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;{{subjectInfo.score}}分&nbsp;</span>)
+                </span>
+            </div>
+
+            <ul class="subject-options"
+                v-for="option in options"
+                :key="option.id">
+                <li class="subject-option">
+                    <input class="toggle"
+                           type="checkbox"
+                           :checked="isChecked(option.optionName)"
+                           :id="'option' + option.id"
+                           @change="toggleOption($event, option)">
+                    <label :for="'option' + option.id">
+                        <span class="subject-option-prefix">{{ option.optionName + '.' }}&nbsp;</span>
+                        <span v-html="option.optionContent"
+                              class="subject-option-prefix" />
+                    </label>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'MultipleChoices',
+    data () {
+        return {
+            subjectCount: 0,
+            subjectInfo: {
+                subjectName: '',
+                score: 0
+            },
+            options: [],
+            userAnswer: [],
+            index: ''
+        }
+    },
+    watch: {
+
+    },
+    methods: {
+        getAnswer () {
+            return this.userAnswer.join(',')
+        },
+        setAnswer (answer) {
+            // if (isNotEmpty(answer)) {
+            this.userAnswer = answer.split(',')
+            // }
+        },
+        setSubjectInfo (subject, subjectCount, index) {
+            this.subjectCount = subjectCount
+            this.subjectInfo = subject
+            if (subject.hasOwnProperty('examSubjectOptions')) {
+                this.options = subject.examSubjectOptions
+            }
+            if (subject.hasOwnProperty('answer')) {
+                this.setAnswer(subject.answer)
+            }
+            this.index = index + '.'
+        },
+        getSubjectInfo () {
+            this.subjectInfo.options = this.options
+            return this.subjectInfo
+        },
+        // 选中选项
+        toggleOption ($event, option) {
+
+            if ($event.target.checked) {
+                if (!this.userAnswer.includes(option.optionName)) {
+                    this.userAnswer.push(option.optionName)
+                }
+            } else {
+                this.userAnswer.splice(this.userAnswer.findIndex(item => item === option.optionName), 1)
+            }
+        },
+        isChecked (optionName) {
+            return this.userAnswer.includes(optionName)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../../assets/css/subject.scss';
+.subject-options > li label {
+    height: 36px;
+    line-height: 28px !important;
+}
+</style>
diff --git a/src/components/Subjects/PracticalOperation/index.vue b/src/components/Subjects/PracticalOperation/index.vue
new file mode 100644
index 0000000..83ce13c
--- /dev/null
+++ b/src/components/Subjects/PracticalOperation/index.vue
@@ -0,0 +1,190 @@
+<template>
+    <div>
+        <div class="subject-content">
+            <div class="subject-title">
+                {{ index }}
+                <span class="subject-title-content"
+                      v-html="subjectInfo.subjectName" />
+                <span class="subject-title-content">
+                    (&nbsp;实操题&nbsp;<span v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;{{subjectInfo.score}}分&nbsp;</span>)
+                </span>
+            </div>
+
+            <ul class="subject-options"
+                v-for="(option, index) in options"
+                :key="option.id">
+                <li class="subject-option pbox">
+
+                    <span class="num"
+                          @click="selectCheckbox($event, option)"> {{ userAnswer[index].value }} </span>
+
+                    <label :for="'option' + option.id">
+                        <span class="subject-option-prefix">{{ option.optionName + '.' }}&nbsp;</span>
+                        <span v-html="option.optionContent"
+                              class="subject-option-prefix" />
+                    </label>
+
+                </li>
+            </ul>
+
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: 'MultipleChoices',
+    data () {
+        return {
+            subjectCount: 0,
+            subjectInfo: {
+                subjectName: '',
+                score: 0
+            },
+            options: [],
+            userAnswer: [],
+            index: ''
+        }
+    },
+    watch: {
+
+    },
+    methods: {
+        getAnswer () {
+            return this.userAnswer
+        },
+        setAnswer (answer, option) {
+            console.log(answer);
+            if (answer != '') {
+
+                this.userAnswer = answer
+
+            } else {
+                this.userAnswer = []
+                option.forEach(item => {
+                    this.userAnswer.push({ key: item.optionName, value: '' })
+                })
+            }
+        },
+        setSubjectInfo (subject, subjectCount, index) {
+            this.subjectCount = subjectCount
+            this.subjectInfo = subject
+            if (subject.hasOwnProperty('examSubjectOptions')) {
+                this.options = subject.examSubjectOptions
+            }
+            if (subject.hasOwnProperty('answer')) {
+                this.setAnswer(subject.answer, subject.examSubjectOptions)
+            }
+            this.index = index + '.'
+        },
+        getSubjectInfo () {
+            this.subjectInfo.options = this.options
+            return this.subjectInfo
+        },
+
+        selectCheckbox ($event, option) {
+
+            var flag = false;
+
+            this.userAnswer.forEach(item => {
+                if (item.value != "") {
+                    flag = true
+                }
+            })
+
+            this.userAnswer
+
+            if (flag == true) {
+                // 其中最少有一个有值的
+                var onlyFlag = false;
+                var onlyValue = '';
+                var ind = 0;
+                this.userAnswer.forEach(item => {
+                    if (item.value != '' && item.value > ind) {
+                        ind = item.value
+                    }
+                })
+
+                this.userAnswer.forEach(item => {
+                    if (item.key == option.optionName) {
+                        if (item.value != '') {
+                            onlyValue = item.value
+                            onlyFlag = true
+                            item.value = ''
+                        } else {
+                            item.value = ind + 1
+                        }
+                    }
+                })
+
+                this.userAnswer.forEach(item => {
+                    if (onlyFlag == true) {
+
+                        if (item.value > onlyValue) {
+                            item.value -= 1
+                        }
+
+                    }
+                })
+
+
+            } else {
+                // 全部都为空
+                this.userAnswer.forEach(item => {
+                    if (item.key == option.optionName) {
+                        item.value = 1
+                    }
+                })
+            }
+
+
+            console.log(this.userAnswer)
+
+        },
+
+        isChecked (optionName) {
+            return this.userAnswer.includes(optionName)
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../../assets/css/subject.scss';
+
+.pbox .num {
+    // margin: 2px;
+    // text-align: center;
+    // vertical-align: middle;
+    // display: inline-block;
+    // width: 20px;
+    // height: 20px;
+    // border: 1px solid #999;
+    width: 26px;
+    height: 26px;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    margin: auto 0;
+    // opacity: 0;
+    text-align: center;
+    font-size: 18px;
+    font-weight: bold;
+    border: 1px solid #cfcfcf;
+    background-color: #ff9;
+    cursor: pointer;
+}
+
+.subject-options > li label {
+    height: 36px;
+    line-height: 28px !important;
+}
+.pbox.checked {
+    border: 1px solid #99f;
+    background-color: #ccf;
+}
+.pbox.checked .num {
+    border: 1px solid #ff0;
+    background-color: #ff9;
+}
+</style>
diff --git a/src/components/Subjects/ShortAnswer/index.vue b/src/components/Subjects/ShortAnswer/index.vue
new file mode 100644
index 0000000..3e29254
--- /dev/null
+++ b/src/components/Subjects/ShortAnswer/index.vue
@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <div class="subject-content">
+      <div class="subject-title">
+        {{ index }}
+        <span class="subject-title-content" v-html="subjectInfo.subjectName"/>
+        <span class="subject-title-content" v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;({{subjectInfo.score}})分</span>
+        <div class="subject-tinymce">
+          <tinymce ref="editor" :height="height" v-model="userAnswer"/>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Tinymce from '@/components/Tinymce'
+
+export default {
+  name: 'ShortAnswer',
+  components: {
+    Tinymce
+  },
+  props: {
+    height: {
+      type: Number,
+      required: false,
+      default: 300
+    }
+  },
+  data () {
+    return {
+      subjectCount: 0,
+      subjectInfo: {
+        subjectName: '',
+        score: 0
+      },
+      userAnswer: '',
+      index: ''
+    }
+  },
+  methods: {
+    getAnswer () {
+      return this.userAnswer
+    },
+    setAnswer (answer) {
+      this.userAnswer = answer
+    },
+    setSubjectInfo (subject, subjectCount, index) {
+      this.subjectCount = subjectCount
+      this.subjectInfo = subject
+      if (subject.hasOwnProperty('answer')) {
+        this.setAnswer(subject.answer.answer)
+      }
+      this.index = index + '.'
+    },
+    getSubjectInfo () {
+      return this.subjectInfo
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+  @import "../../../assets/css/subject.scss";
+  .subject-tinymce {
+    margin: 12px;
+  }
+  .subject-options > li label {
+    height: 36px;
+    line-height: 28px !important;
+}
+</style>
diff --git a/src/components/Tinymce/components/editorImage.vue b/src/components/Tinymce/components/editorImage.vue
new file mode 100644
index 0000000..6a743a6
--- /dev/null
+++ b/src/components/Tinymce/components/editorImage.vue
@@ -0,0 +1,103 @@
+<template>
+  <div class="upload-container">
+    <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">上传图片
+    </el-button>
+    <el-dialog :visible.sync="dialogVisible">
+      <el-upload
+        :multiple="true"
+        :file-list="fileList"
+        :show-file-list="true"
+        :on-remove="handleRemove"
+        :on-success="handleSuccess"
+        :before-upload="beforeUpload"
+        class="editor-slide-upload"
+        action="https://httpbin.org/post"
+        list-type="picture-card">
+        <el-button size="small" type="primary">点击上传</el-button>
+      </el-upload>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+      <el-button type="primary" @click="handleSubmit">确 定</el-button>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import { getToken } from 'api/qiniu'
+
+export default {
+  name: 'EditorSlideUpload',
+  props: {
+    color: {
+      type: String,
+      default: '#1890ff'
+    }
+  },
+  data () {
+    return {
+      dialogVisible: false,
+      listObj: {},
+      fileList: []
+    }
+  },
+  methods: {
+    checkAllSuccess () {
+      return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess)
+    },
+    handleSubmit () {
+      const arr = Object.keys(this.listObj).map(v => this.listObj[v])
+      if (!this.checkAllSuccess()) {
+        this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!')
+        return
+      }
+      this.$emit('successCBK', arr)
+      this.listObj = {}
+      this.fileList = []
+      this.dialogVisible = false
+    },
+    handleSuccess (response, file) {
+      const uid = file.uid
+      const objKeyArr = Object.keys(this.listObj)
+      for (let i = 0, len = objKeyArr.length; i < len; i++) {
+        if (this.listObj[objKeyArr[i]].uid === uid) {
+          this.listObj[objKeyArr[i]].url = response.files.file
+          this.listObj[objKeyArr[i]].hasSuccess = true
+          return
+        }
+      }
+    },
+    handleRemove (file) {
+      const uid = file.uid
+      const objKeyArr = Object.keys(this.listObj)
+      for (let i = 0, len = objKeyArr.length; i < len; i++) {
+        if (this.listObj[objKeyArr[i]].uid === uid) {
+          delete this.listObj[objKeyArr[i]]
+          return
+        }
+      }
+    },
+    beforeUpload (file) {
+      const _self = this
+      const _URL = window.URL || window.webkitURL
+      const fileName = file.uid
+      this.listObj[fileName] = {}
+      return new Promise((resolve, reject) => {
+        const img = new Image()
+        img.src = _URL.createObjectURL(file)
+        img.onload = function () {
+          _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height }
+        }
+        resolve(true)
+      })
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.editor-slide-upload {
+  margin-bottom: 20px;
+  /deep/ .el-upload--picture-card {
+    width: 100%;
+  }
+}
+</style>
diff --git a/src/components/Tinymce/index.vue b/src/components/Tinymce/index.vue
new file mode 100644
index 0000000..768d04c
--- /dev/null
+++ b/src/components/Tinymce/index.vue
@@ -0,0 +1,162 @@
+<template>
+  <div :class="{fullscreen:fullscreen}" class="tinymce-container editor-container">
+    <textarea :id="tinymceId" class="tinymce-textarea"/>
+  </div>
+</template>
+
+<script>
+import editorImage from './components/editorImage'
+import plugins from './plugins'
+import toolbar from './toolbar'
+
+export default {
+  name: 'Tinymce',
+  components: { editorImage },
+  props: {
+    id: {
+      type: String,
+      default: function () {
+        return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
+      }
+    },
+    value: {
+      type: String,
+      default: ''
+    },
+    toolbar: {
+      type: Array,
+      required: false,
+      default () {
+        return []
+      }
+    },
+    menubar: {
+      type: String,
+      default: 'file edit insert view format table'
+    },
+    height: {
+      type: Number,
+      required: false,
+      default: 360
+    }
+  },
+  data () {
+    return {
+      hasChange: false,
+      hasInit: false,
+      tinymceId: this.id,
+      fullscreen: false,
+      languageTypeList: {
+        'en': 'en',
+        'zh': 'zh_CN'
+      }
+    }
+  },
+  computed: {
+    language () {
+      return this.languageTypeList['zh']
+    }
+  },
+  watch: {
+    value (val) {
+      if (!this.hasChange && this.hasInit) {
+        this.$nextTick(() =>
+          window.tinymce.get(this.tinymceId).setContent(val || ''))
+      }
+    },
+    language () {
+      this.destroyTinymce()
+      this.$nextTick(() => this.initTinymce())
+    }
+  },
+  mounted () {
+    this.initTinymce()
+  },
+  activated () {
+    this.initTinymce()
+  },
+  deactivated () {
+    this.destroyTinymce()
+  },
+  destroyed () {
+    this.destroyTinymce()
+  },
+  methods: {
+    initTinymce () {
+      const _this = this
+      window.tinymce.init({
+        language: this.language,
+        selector: `#${this.tinymceId}`,
+        height: this.height,
+        body_class: 'panel-body ',
+        object_resizing: false,
+        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
+        menubar: this.menubar,
+        plugins: plugins,
+        end_container_on_empty_block: true,
+        powerpaste_word_import: 'clean',
+        code_dialog_height: 450,
+        code_dialog_width: 1000,
+        advlist_bullet_styles: 'square',
+        advlist_number_styles: 'default',
+        imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
+        default_link_target: '_blank',
+        link_title: false,
+        nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
+        init_instance_callback: editor => {
+          if (_this.value) {
+            editor.setContent(_this.value)
+          }
+          _this.hasInit = true
+          editor.on('NodeChange Change KeyUp SetContent', () => {
+            this.hasChange = true
+            this.$emit('input', editor.getContent())
+          })
+        },
+        setup (editor) {
+          editor.on('FullscreenStateChanged', (e) => {
+            _this.fullscreen = e.state
+          })
+        }
+      })
+    },
+    destroyTinymce () {
+      if (window.tinymce.get(this.tinymceId)) {
+        window.tinymce.get(this.tinymceId).destroy()
+      }
+    },
+    setContent (value) {
+      window.tinymce.get(this.tinymceId).setContent(value)
+    },
+    getContent () {
+      return window.tinymce.get(this.tinymceId).getContent()
+    }
+  }
+}
+</script>
+
+<style scoped>
+.tinymce-container {
+  position: relative;
+}
+.tinymce-container>>>.mce-fullscreen {
+  z-index: 10000;
+}
+.tinymce-textarea {
+  visibility: hidden;
+  z-index: -1;
+}
+.editor-custom-btn-container {
+  position: absolute;
+  right: 4px;
+  top: 4px;
+  /*z-index: 2005;*/
+}
+.fullscreen .editor-custom-btn-container {
+  z-index: 10000;
+  position: fixed;
+}
+.editor-upload-btn {
+  display: inline-block;
+}
+</style>
diff --git a/src/components/Tinymce/plugins.js b/src/components/Tinymce/plugins.js
new file mode 100644
index 0000000..8fc207e
--- /dev/null
+++ b/src/components/Tinymce/plugins.js
@@ -0,0 +1,7 @@
+// Any plugins you want to use has to be imported
+// Detail plugins list see https://www.tinymce.com/docs/plugins/
+// Custom builds see https://www.tinymce.com/download/custom-builds/
+
+const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
+
+export default plugins
diff --git a/src/components/Tinymce/toolbar.js b/src/components/Tinymce/toolbar.js
new file mode 100644
index 0000000..7d6c2c7
--- /dev/null
+++ b/src/components/Tinymce/toolbar.js
@@ -0,0 +1,6 @@
+// Here is a list of the toolbar
+// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
+
+const toolbar = ['bold italic underline strikethrough alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
+
+export default toolbar
diff --git a/src/config/env.js b/src/config/env.js
index 5270f73..1398ad9 100644
--- a/src/config/env.js
+++ b/src/config/env.js
@@ -1,5 +1,5 @@
 // 阿里矢量图标库配置
-let iconfontVersion = ['567566_pwc3oottzol'];
+let iconfontVersion = ['567566_pwc3oottzol', '2680691_r9wggg2tnk'];
 let iconfontUrl = `//at.alicdn.com/t/font_$key.css`;
 
 let baseUrl = '';
diff --git a/src/config/iconList.js b/src/config/iconList.js
index e79647e..40463a8 100644
--- a/src/config/iconList.js
+++ b/src/config/iconList.js
@@ -66,6 +66,17 @@
       "iconfont iconicon_add",
       "iconfont icongithub",
       "iconfont icongitee2",
+
+
+
+
+
+      "iconfont icon-baoming",
+      "iconfont icon-tiku",
+      "iconfont icon-duoxiaoliankaokaowuguanli",
+      "iconfont icon-kaoshi",
+      "iconfont icon-shijuan",
+      "iconfont icon-chengji",
     ]
   },
   {
diff --git a/src/const/constant.js b/src/const/constant.js
new file mode 100644
index 0000000..b50ef68
--- /dev/null
+++ b/src/const/constant.js
@@ -0,0 +1,10 @@
+export const nextSubjectType = {
+  last: 1,
+  next: 0,
+  current: 2
+}
+
+export const answerType = {
+  'true': 'right',
+  'false': 'incorrect'
+}
diff --git a/src/const/errorCode.js b/src/const/errorCode.js
new file mode 100644
index 0000000..032a908
--- /dev/null
+++ b/src/const/errorCode.js
@@ -0,0 +1,12 @@
+export default {
+  '478': '验证码错误,请重新输入',
+  '479': '验证码已过期,请重新输入',
+  '401': '当前操作没有权限',
+  '403': '当前操作没有权限',
+  '400': '用户名不存在或密码错误',
+  '500': '服务器内部错误,请反馈给管理员',
+  '4015': '服务不可用',
+  '4020': '验证码错误',
+  '4026': '验证码已过期,请重新获取',
+  'default': '系统未知错误,请反馈给管理员'
+}
diff --git a/src/store/modules/common.js b/src/store/modules/common.js
index ec24a59..9b99ee9 100644
--- a/src/store/modules/common.js
+++ b/src/store/modules/common.js
@@ -8,13 +8,13 @@
 const common = {
 
   state: {
-    language: getStore({name: 'language'}) || 'zh',
+    language: getStore({ name: 'language' }) || 'zh',
     isCollapse: false,
     isFullScren: false,
     isMenu: true,
     isShade: false,
     screen: -1,
-    isLock: getStore({name: 'isLock'}) || false,
+    isLock: getStore({ name: 'isLock' }) || false,
     showTag: true,
     showDebug: true,
     showCollapse: true,
@@ -24,9 +24,9 @@
     showTheme: true,
     showMenu: true,
     showColor: true,
-    colorName: getStore({name: 'colorName'}) || '#409EFF',
-    themeName: getStore({name: 'themeName'}) || 'theme-default',
-    lockPasswd: getStore({name: 'lockPasswd'}) || '',
+    colorName: getStore({ name: 'colorName' }) || '#409EFF',
+    themeName: getStore({ name: 'themeName' }) || 'theme-bule',
+    lockPasswd: getStore({ name: 'lockPasswd' }) || '',
     website: website,
   },
   mutations: {
diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss
index 54c3e92..1b8abea 100644
--- a/src/styles/element-ui.scss
+++ b/src/styles/element-ui.scss
@@ -25,7 +25,6 @@
   display: none;
 }
 
-
 .el-message__icon,
 .el-message__content {
   display: inline-block;
@@ -49,12 +48,19 @@
   padding: 0 !important;
 }
 
-.el-dropdown-menu__item--divided:before, .el-menu, .el-menu--horizontal > .el-menu-item:not(.is-disabled):focus, .el-menu--horizontal > .el-menu-item:not(.is-disabled):hover, .el-menu--horizontal > .el-submenu .el-submenu__title:hover {
+.el-dropdown-menu__item--divided:before,
+.el-menu,
+.el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
+.el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
+.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
   background-color: transparent;
 }
 
-
-.el-dropdown-menu__item--divided:before, .el-menu, .el-menu--horizontal > .el-menu-item:not(.is-disabled):focus, .el-menu--horizontal > .el-menu-item:not(.is-disabled):hover, .el-menu--horizontal > .el-submenu .el-submenu__title:hover {
+.el-dropdown-menu__item--divided:before,
+.el-menu,
+.el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
+.el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
+.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
   background-color: transparent !important;
 }
 
@@ -69,3 +75,130 @@
 .el-divider--horizontal {
   margin: 12px 0 !important;
 }
+
+//表格斑马纹
+.el-table tr:nth-child(2n -1) {
+  // background-color: rgba($color: #000000, $alpha: 0.1) !important;
+}
+
+//顶部搜索栏
+.el-card.is-never-shadow.avue-crud__search {
+  position: absolute !important;
+  width: calc(100% - 220px) !important;
+  z-index: 500 !important;
+  border: none !important;
+  box-shadow: none !important;
+  height: 40px;
+}
+
+//取消顶部搜索栏
+.user .el-card.is-never-shadow.avue-crud__search {
+  position: relative !important;
+  width: auto !important;
+  z-index: 500 !important;
+  border: none !important;
+  box-shadow: none !important;
+  height: auto;
+}
+
+.desk .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 360px) !important;
+}
+.securityGuard .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 300px) !important;
+  left: 120px;
+}
+.securityUnit .el-card.is-never-shadow.avue-crud__search {
+  left: 200px;
+  width: calc(100% - 380px) !important;
+}
+.equipments .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px;
+}
+.dispatch .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px;
+}
+.dispatchChildoperable .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 280px) !important;
+  left: 90px;
+}
+.workreply .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px !important;
+}
+.recruitmentManagement .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px !important;
+}
+
+.hasButOne .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 300px) !important;
+  left: 120px !important;
+}
+.hasButTwo .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px !important;
+}
+.topmenu .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 390px) !important;
+  left: 220px !important;
+}
+.hasButThree .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 510px) !important;
+  left: 310px !important;
+}
+.avue-form {
+  position: relative;
+  top: -10px;
+}
+//顶部按钮栏
+.avue-crud__menu {
+  height: 60px;
+}
+//顶部按钮
+.avue-crud .avue-crud__left .el-button,
+.avue-crud .avue-crud__right .el-button,
+.avue-form .avue-crud__left .el-button,
+.avue-form .avue-crud__right .el-button {
+  position: relative;
+  top: 5px;
+}
+
+//左侧导航栏
+.avue-logo {
+  background-color: #409eff !important;
+  color: #fff !important;
+}
+.avue-sidebar {
+  background-color: #fff !important;
+}
+
+.avue-header {
+  background-color: #409eff !important;
+  color: #fff !important;
+}
+
+.avue-sidebar .el-menu-item span,
+.avue-sidebar .el-submenu__title span,
+.avue-sidebar .el-submenu__title i,
+.avue-sidebar .el-menu-item i {
+  color: #000 !important;
+}
+
+// 菜单 活动背景
+.avue-sidebar .el-menu-item.is-active {
+  background-color: #409eff !important;
+}
+.avue-sidebar .el-menu-item.is-active span,
+.el-menu-item.is-active i {
+  color: #fff !important;
+}
+
+//top 导航 按钮
+.el-menu--horizontal > .el-menu-item.is-active,
+.avue-top,
+.el-dropdown {
+  color: #fff !important;
+}
diff --git a/src/views/applyexam/index.vue b/src/views/applyexam/index.vue
new file mode 100644
index 0000000..17c3142
--- /dev/null
+++ b/src/views/applyexam/index.vue
@@ -0,0 +1,461 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-19 19:39:45
+ * menu-name 报名考试
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="obj"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-save="questionBankRowSave"
+                               @row-del="questionBankRowDel">
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                        <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="small"
+                                       icon="el-icon-delete"
+                                       @click="questionBankHandleDelete">删 除
+                            </el-button>
+                        </template>
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+
+import {
+    getApplyList,
+    addApply,
+    remove
+} from "@/api/examapi/applyexam";
+import { mapState } from 'vuex'
+
+
+
+
+export default {
+    data () {
+
+        return {
+            obj: {
+                name: '张三',
+            },
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: true,
+                editBtn: false,
+                addBtn: true,
+                selection: true,
+                menu: true,
+                // 导出按钮
+                excelBtn: true,
+                viewBtn: false,
+
+                // title: '题库',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menuWidth: 286,
+
+                column: [
+                    {
+                        label: "保安姓名",
+                        prop: "name",
+                        type: 'tree',
+                        dicUrl: '',
+                        search: true,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        props: {
+                            label: "title",
+                            value: "id",
+                        },
+                        rules: [{
+                            required: true,
+                            message: "请选择保安姓名",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "试卷名称",
+                        prop: "examName",
+                        type: 'tree',
+                        dicUrl: '/api/exampaper/page-tree',
+                        // search: true,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        props: {
+                            label: "examName",
+                            value: "id",
+                        },
+                        rules: [{
+                            required: true,
+                            message: "请选择试卷名称",
+                            trigger: "blur"
+                        }],
+                        width: 220
+                    },
+                    {
+                        label: "所属公司",
+                        prop: "deptName",
+                        search: true,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请选择所属公司",
+                            trigger: "blur"
+                        }],
+                        width: 220
+                    },
+                    {
+                        label: "准考证号",
+                        prop: "candidateNo",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请选择准考证号",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "试卷分数",
+                        prop: "paperScore",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false
+                    },
+                    {
+                        label: "报名时间",
+                        prop: "applyTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: true,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        value: (new Date().getFullYear() + '-' + (new Date().getMonth() + 1 < 10
+                            ? "0" + (new Date().getMonth() + 1)
+                            : new Date().getMonth() + 1) + '-' + (new Date().getDate() < 10
+                                ? "0" + new Date().getDate()
+                                : new Date().getDate()) + ' ' + (new Date().getHours() < 10
+                                    ? "0" + new Date().getHours()
+                                    : new Date().getHours()) + ':' + (new Date().getMinutes() < 10
+                                        ? "0" + new Date().getMinutes()
+                                        : new Date().getMinutes()) + ':' + (new Date().getSeconds() < 10
+                                            ? "0" + new Date().getSeconds()
+                                            : new Date().getSeconds())),
+
+                        width: 250
+                    },
+                    {
+                        label: "考试时间",
+                        prop: "examTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+                        width: 250
+                    }
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+
+    watch: {
+        "form.examname": {
+            // form是表单或者表格绑定的数据集,v-model='form'
+            handler (val) {
+                if (val) {
+                    //地址截取,从县/区开始截取,并且取从县区第一个出现的位置开始
+                    var address = val.formattedAddress.toString();
+                    if (address.search("县") != -1) {
+                        this.form.address = address.substring(
+                            address.indexOf("县") + 1,
+                            address.length
+                        );
+                    }
+                    if (address.search("区") != -1) {
+                        this.form.address = address.substring(
+                            address.indexOf("区") + 1,
+                            address.length
+                        );
+                    }
+                }
+            },
+            immediate: true,
+        },
+    },
+    created () {
+
+      console.log(this.userInfo)
+
+      if (this.userInfo.role_name.indexOf('ksxtadmin') != -1) {
+
+        this.questionBankOption.column[0].dicUrl = "/api/blade-system/dept/lazy-tree-user?parentId="
+      } else {
+        this.questionBankOption.column[0].dicUrl = "/api/blade-system/dept/lazy-tree-user?parentId=" + this.userInfo.dept_id
+
+      }
+
+
+    },
+    mounted () {
+
+
+    },
+    computed: {
+        ...mapState({
+            userInfo: state => state.user.userInfo
+        }),
+        ids () {
+            let ids = [];
+            this.questionBankSelectionList.forEach(ele => {
+                ids.push(ele.id);
+            });
+            return ids.join(",");
+        },
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getApplyList(page.currentPage, page.pageSize, Object.assign(params, this.questionBankQuery)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        // 新增
+        questionBankRowSave (row, done, loading) {
+
+            addApply({ userId: row.name, examId: row.examName, applyTime: row.applyTime }).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+
+        questionBankRowDel (row) {
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(row.id);
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                });
+        },
+
+        questionBankHandleDelete () {
+            if (this.questionBankSelectionList.length === 0) {
+                this.$message.warning("请选择至少一条数据");
+                return;
+            }
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(this.ids);
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                    this.$refs.questionBankCrud.toggleSelection();
+                });
+        },
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/views/authority/role.vue b/src/views/authority/role.vue
index 9a9895c..a414b39 100644
--- a/src/views/authority/role.vue
+++ b/src/views/authority/role.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="hasButThree">
     <avue-crud
       :option="option"
       :table-loading="loading"
diff --git a/src/views/desk/notice.vue b/src/views/desk/notice.vue
index 573c6fb..0a57ea6 100644
--- a/src/views/desk/notice.vue
+++ b/src/views/desk/notice.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="desk">
     <avue-crud
       :option="option"
       :table-loading="loading"
diff --git a/src/views/dispatch/dispatch.vue b/src/views/dispatch/dispatch.vue
index 68e5295..e8f66ec 100644
--- a/src/views/dispatch/dispatch.vue
+++ b/src/views/dispatch/dispatch.vue
@@ -112,6 +112,7 @@
       option: {
         tip: false,
         // card: true,
+        index: true,
         searchSize: "mini",
         searchMenuSpan: 6,
         height: 623,
diff --git a/src/views/dispatch/dispatchChildoperable.vue b/src/views/dispatch/dispatchChildoperable.vue
index 1637016..fd346fc 100644
--- a/src/views/dispatch/dispatchChildoperable.vue
+++ b/src/views/dispatch/dispatchChildoperable.vue
@@ -81,6 +81,7 @@
 
 export default {
   data() {
+    let baseUrl = "https://cli.avuejs.com/api/area";
     return {
       // typeTABS: {}, //标签页
       // optionTABS: {
@@ -158,7 +159,7 @@
         // addBtn: false,
         // menuWidth: 160,
         align: "center",
-        // selection: true,
+        selection: true,
         column: [
           // 派遣服务公司登记
           // {
@@ -171,50 +172,73 @@
           //     // editDisplay: false,
           //     // addDisplay: false
           // },
-          {
-            label: "保安公司",
-            prop: "deptId",
-            labelWidth: 120,
-            searchLabelWidth: 120,
-            searchSpan: 4,
-            dicUrl:
-              "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
-            props: {
-              label: "title",
-              value: "id",
-            },
-            search: true,
-            overHidden: true,
-            type: "select",
-            rules: [
-              {
-                required: true,
-                message: "请输入保安公司",
-                trigger: "blur",
-              },
-            ],
-          },
+          // {
+          //   label: "保安公司",
+          //   prop: "deptId",
+          //   labelWidth: 120,
+          //   searchLabelWidth: 120,
+          //   searchSpan: 4,
+          //   dicUrl:
+          //     "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
+          //   props: {
+          //     label: "title",
+          //     value: "id",
+          //   },
+          //   search: true,
+          //   overHidden: true,
+          //   type: "select",
+          //   rules: [
+          //     {
+          //       required: true,
+          //       message: "请输入保安公司",
+          //       trigger: "blur",
+          //     },
+          //   ],
+          // },
           {
             label: "派遣单位",
             prop: "dispatcherCompany",
             addDisplay: false,
             editDisplay: false,
           },
+          // {
+          //   label: "派遣单位",
+          //   prop: "dispatcherUnitId",
+          //   labelWidth: 120,
+          //   searchLabelWidth: 120,
+          //   dicUrl: "/api/dispatcherUnit/page-tree",
+          //   props: {
+          //     label: "name",
+          //     value: "id",
+          //   },
+          //   hide: true,
+          //   searchSpan: 4,
+          //   search: true,
+          //   overHidden: true,
+          //   type: "tree",
+          //   rules: [
+          //     {
+          //       required: true,
+          //       message: "请输入保安公司",
+          //       trigger: "blur",
+          //     },
+          //   ],
+          // },
           {
-            label: "派遣单位",
-            prop: "dispatcherUnitId",
+            label: "保安公司",
+            prop: "deptId",
             labelWidth: 120,
             searchLabelWidth: 120,
-            dicUrl: "/api/dispatcherUnit/page-tree",
-            props: {
-              label: "name",
-              value: "id",
-            },
-            hide: true,
-            searchSpan: 4,
             search: true,
             overHidden: true,
             type: "tree",
+            cascaderItem: ["name"],
+            // cascaderItem: ["city", "area"],
+            props: {
+              label: "title",
+              value: "id",
+            },
+            dicUrl: `/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697`,
             rules: [
               {
                 required: true,
@@ -224,21 +248,66 @@
             ],
           },
           {
-            label: "保安人名称",
+            width: 120,
+            label: "保安员",
             prop: "name",
-            search: true,
-            searchSpan: 4,
             labelWidth: 120,
-            searchLabelWidth: 120,
-            // overHidden: true
+            type: "tree",
+            cell: true,
+            props: {
+              label: "realName",
+              value: "id",
+            },
+            dicUrl: `/api/blade-user/page-security-unit?deptId={{deptId}}`,
             rules: [
               {
                 required: true,
-                message: "请输入保安人名称",
-                trigger: "click",
+                message: "请选择保安",
+                trigger: "blur",
               },
             ],
           },
+          // {
+          //   width: 120,
+          //   label: "保安人名称",
+          //   prop: "area",
+          //   cell: true,
+          //   props: {
+          //     label: "name",
+          //     value: "code",
+          //   },
+          //   type: "select",
+          //   dicUrl: `${baseUrl}/getArea/{{key}}`,
+          //   rules: [
+          //     {
+          //       required: true,
+          //       message: "请选择地区",
+          //       trigger: "blur",
+          //     },
+          //   ],
+          // },
+          // {
+          //   label: "保安人名称",
+          //   prop: "name",
+          //   search: true,
+          //   searchSpan: 4,
+          //   labelWidth: 120,
+          //   searchLabelWidth: 120,
+          //   // overHidden: true
+          //   type: "tree",
+          //   dicUrl: "/api/blade-user/page-security",
+          //   props: {
+          //     label: "realName",
+          //     value: "postId",
+          //   },
+          //   rules: [
+          //     {
+          //       required: true,
+          //       message: "请输入保安人名称",
+          //       trigger: "click",
+          //     },
+          //   ],
+          // },
           {
             label: "身份证",
             prop: "cardid",
diff --git a/src/views/exam/examSubjects.vue b/src/views/exam/examSubjects.vue
new file mode 100644
index 0000000..5948425
--- /dev/null
+++ b/src/views/exam/examSubjects.vue
@@ -0,0 +1,328 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 15:47:06
+ * menu-name 题目管理
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="obj"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-save="questionBankRowSave"
+                               @row-update="questionBankRowUpdate"
+                               @row-del="questionBankRowDel">
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                        <template slot-scope="{row}"
+                                  slot="examstate">
+                            <el-tag>{{row.examstate == 0 ? '已发布' : '草稿'}}</el-tag>
+                        </template>
+
+                        <!-- <template slot="menu">
+                            <el-button type="text"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       @click="questionBankHandleDel">删除
+                            </el-button>
+                        </template> -->
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+
+import {
+    getPaperList,
+    updatePaper,
+    remove
+} from "@/api/examapi/examSubjects";
+
+
+
+export default {
+    data () {
+
+        var validatePass = (rule, value, callback) => {
+            console.log(value)
+            if (value == undefined || value == '') {
+                callback(new Error('请输入分数'));
+                return;
+            } else if (value !== '' && isNaN(value) == true) {
+                callback(new Error('请输入数字'));
+            } else if (value <= 0) {
+                callback(new Error('分数设置请大于0'));
+            } else {
+                callback();
+            }
+        };
+
+        return {
+            obj: {
+                name: '张三',
+            },
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: true,
+                editBtn: true,
+                addBtn: false,
+                selection: false,
+                // 导出按钮
+                excelBtn: false,
+                viewBtn: false,
+
+
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                  indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+
+                // 操作栏宽度
+                menu: true,
+                menuWidth: 180,
+
+                column: [
+                    {
+                        label: "题目名称",
+                        prop: "subjectName",
+                        span: 24,
+                        search: true,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        row: true,
+                        rules: [{
+                            required: true,
+                            message: "请输入考试名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "题目类型",
+                        prop: "choicesType",
+                        type: "select",
+                        search: true,
+                        searchSpan: 4,
+                        searchLabelWidth: 80,
+                        value: 0,
+                        dicData: [{
+                            label: '单选题',
+                            value: 0
+                        }, {
+                            label: '多选题',
+                            value: 1,
+                        }, {
+                            label: '判断题',
+                            value: 2,
+                        }],
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 106
+                    },
+                    {
+                        label: "分值",
+                        prop: "score",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+
+                        rules: [{ validator: validatePass, required: true, trigger: 'blur' }],
+                        width: 106
+                    }
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+
+            this.questionBankQuery.id = this.$route.query.id;
+
+            getPaperList(page.currentPage, page.pageSize, Object.assign(params, this.questionBankQuery)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        questionBankRowDel (row) {
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove({ paperid: this.$route.query.id, subjectid: row.id });
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                });
+        },
+
+        questionBankRowSave (row, done, loading) {
+            console.log(row, 898989);
+
+            add(row).then(() => {
+                this.initFlag = false;
+                this.onLoad(this.page);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+        questionBankRowUpdate (row, index, done, loading) {
+
+            updatePaper({ value: row.score, id: row.id }).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/views/exam/examination.vue b/src/views/exam/examination.vue
new file mode 100644
index 0000000..4a8b01b
--- /dev/null
+++ b/src/views/exam/examination.vue
@@ -0,0 +1,478 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 17:11:18
+ * menu-name 试卷管理
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="form"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-save="questionBankRowSave"
+                               @row-update="questionBankRowUpdate"
+                               @row-del="questionBankRowDel">
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                        <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="small"
+                                       icon="el-icon-delete"
+                                       @click="questionBankHandleDelete">删 除
+                            </el-button>
+                        </template>
+
+                        <template slot-scope="{row}"
+                                  slot="examStatus">
+                            <el-tag>{{row.examStatus == 0 ? '已发布' : '草稿'}}</el-tag>
+                        </template>
+
+                        <template slot-scope="{row}"
+                                  slot="menu">
+                            <el-button type="text"
+                                       size="mini"
+                                       icon="el-icon-document"
+                                       @click="subjectManagement(row)">题目管理
+                            </el-button>
+                        </template>
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+import {
+    getList,
+    add,
+    remove,
+    update
+} from "@/api/examapi/examination";
+
+
+export default {
+    data () {
+
+        var validatePass = (rule, value, callback) => {
+            console.log(value)
+            if (value == undefined || value == '') {
+                callback(new Error('请输入分数'));
+                return;
+            } else if (value !== '' && isNaN(value) == true) {
+                callback(new Error('请输入数字'));
+            } else if (value <= 0) {
+                callback(new Error('分数设置请大于0'));
+            } else {
+                callback();
+            }
+        };
+
+        return {
+            form: {},
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: true,
+                editBtn: true,
+                addBtn: true,
+                selection: true,
+                menu: true,
+                // 导出按钮
+                excelBtn: false,
+                viewBtn: true,
+
+                // title: '题库',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menuWidth: 284,
+
+                labelWidth: 140,
+
+                column: [
+                    {
+                        label: "试卷名称",
+                        prop: "examName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入试卷名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "试卷分数",
+                        prop: "totalScore",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+                        rules: [{ validator: validatePass, required: true, trigger: 'blur' }],
+                        width: 100
+                    },
+                    {
+                        label: "考试时间",
+                        prop: "examTime",
+                        type: "daterange",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        startPlaceholder: '考试开始时间',
+                        endPlaceholder: '考试结束时间',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        // display: false,
+                        hide: true,
+                        rules: [{
+                            required: true,
+                            message: "请选择考试时间",
+                            trigger: "blur"
+                        }],
+                        width: 250
+                    },
+                    {
+                        label: "考试开始时间",
+                        prop: "startTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 180
+                    },
+                    {
+                        label: "考试结束时间",
+                        prop: "endTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 180
+                    },
+                    {
+                        label: "创建人",
+                        prop: "creator",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: true,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        hide: true,
+                        display: false,
+                    },
+                    {
+                        label: "备注",
+                        prop: "remark",
+                        span: 24,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false
+                    },
+                    {
+                        label: "注意事项",
+                        prop: "examAttention",
+                        type: "textarea",
+                        span: 24,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 240
+                    },
+
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+    computed: {
+        ids () {
+            let ids = [];
+            this.questionBankSelectionList.forEach(ele => {
+                ids.push(ele.id);
+            });
+            return ids.join(",");
+        },
+    },
+    watch: {
+
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getList(page.currentPage, page.pageSize, Object.assign(params, this.questionBankQuery)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        // 新增
+        questionBankRowSave (row, done, loading) {
+            row.startTime = row.examTime[0]
+            row.endTime = row.examTime[1]
+            row.examTime = JSON.stringify(row.examTime)
+            add(row).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+        questionBankRowUpdate (row, index, done, loading) {
+            if (Array.isArray(row.examTime) != true) {
+                row.examTime = row.examTime.split(",")
+            }
+            row.startTime = row.examTime[0]
+            row.endTime = row.examTime[1]
+            row.examTime = JSON.stringify(row.examTime)
+            update(row).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+
+        questionBankRowDel (row) {
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(row.id);
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                });
+        },
+
+        questionBankHandleDelete () {
+            if (this.questionBankSelectionList.length === 0) {
+                this.$message.warning("请选择至少一条数据");
+                return;
+            }
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(this.ids);
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                    this.$refs.questionBankCrud.toggleSelection();
+                });
+        },
+
+        subjectManagement (row) {
+            this.$router.push({
+                path: `/exam/subjects/${row.id}`,
+                query: row
+            })
+
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/src/views/exam/performance.vue b/src/views/exam/performance.vue
new file mode 100644
index 0000000..78bc56d
--- /dev/null
+++ b/src/views/exam/performance.vue
@@ -0,0 +1,398 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 19:44:47
+ * menu-name 成绩管理
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="obj"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-update="questionBankRowUpdate">
+
+                        <template slot-scope="{ row }"
+                                  slot="learnGrade">
+                            {{ row.learnGrade == -1 ? "暂未录入" : row.learnGrade }}
+                        </template>
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+import {
+    getList,
+    update
+} from "@/api/examapi/performance";
+
+
+
+export default {
+
+
+    data () {
+
+        var validatePass = (rule, value, callback) => {
+            console.log(value)
+            if (value == undefined || value == '') {
+                callback(new Error('请输入实操成绩'));
+                return;
+            } else if (value !== '' && isNaN(value) == true) {
+                callback(new Error('请输入数字'));
+            } else if (value <= 0) {
+                callback(new Error('分数设置请大于0'));
+            } else if (value > 100) {
+                callback(new Error('分数设置请小于100'));
+            } else {
+                callback();
+            }
+        };
+
+        return {
+            obj: {
+                name: '张三',
+            },
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: false,
+                editBtn: true,
+                addBtn: false,
+                selection: false,
+                // 导出按钮
+                excelBtn: true,
+                excelBtnText: '成绩导出',
+                viewBtn: true,
+                title: '成绩',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menu: true,
+                menuWidth: 136,
+                labelWidth: 120,
+
+                column: [
+                    {
+                        label: "试卷名称",
+                        prop: "examName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入试卷名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "保安姓名",
+                        prop: "securityName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入保安姓名",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "所属公司",
+                        prop: "company",
+                        search: true,
+                        searchSpan: 4,
+                        dicUrl: '/api/blade-system/dept/tree',
+                        props: {
+                            label: "title",
+                            value: "id",
+                        },
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入所属公司",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "考试时间",
+                        prop: "examTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        width: 250,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                    },
+                    {
+                        label: "理论成绩",
+                        prop: "theoryGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+                    },
+                    {
+                        label: "实操成绩",
+                        prop: "learnGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{ validator: validatePass, required: true, trigger: 'blur' }],
+                    },
+                    {
+                        label: "总成绩",
+                        prop: "allGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入考试名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "是否合格",
+                        prop: "qualified",
+                        type: 'select',
+                        slot: true,
+                        search: true,
+                        searchSpan: 4,
+                        dicData: [{
+                            label: '合格',
+                            value: 0
+                        }, {
+                            label: '不合格',
+                            value: 1,
+                        }, {
+                            label: '暂未录实操成绩',
+                            value: 2,
+                        }],
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入考试名称",
+                            trigger: "blur"
+                        }]
+                    },
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        questionBankRowUpdate (row, index, done, loading) {
+
+            update({ theoryGrade: row.theoryGrade, learnGrade: row.learnGrade, id: row.id }).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/views/exam/startexam.vue b/src/views/exam/startexam.vue
new file mode 100644
index 0000000..36b593e
--- /dev/null
+++ b/src/views/exam/startexam.vue
@@ -0,0 +1,388 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 17:09:52
+ * menu-name 考试管理
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="form"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange">
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                        <template slot-scope="{row}"
+                                  slot="examStatus">
+                            <el-tag>{{row.examStatus == 0 ? '已发布' : '草稿'}}</el-tag>
+                        </template>
+
+                        <template slot-scope="{row}"
+                                  slot="menu">
+
+                            <el-button type="text"
+                                       size="mini"
+                                       icon="icon-kaoshi"
+                                       class="start-kaoshi"
+
+                                       @click="startExam(row)">开始考试
+                            </el-button>
+                        </template>
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+import {
+    getList,
+} from "@/api/examapi/examination";
+
+
+export default {
+    data () {
+
+        var validatePass = (rule, value, callback) => {
+            console.log(value)
+            if (value == undefined || value == '') {
+                callback(new Error('请输入分数'));
+                return;
+            } else if (value !== '' && isNaN(value) == true) {
+                callback(new Error('请输入数字'));
+            } else if (value <= 0) {
+                callback(new Error('分数设置请大于0'));
+            } else {
+                callback();
+            }
+        };
+
+        return {
+            form: {},
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: false,
+                editBtn: false,
+                addBtn: false,
+                selection: false,
+                menu: true,
+                // 导出按钮
+                excelBtn: false,
+                viewBtn: true,
+
+                // title: '题库',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menuWidth: 246,
+
+                labelWidth: 140,
+
+                column: [
+                    {
+                        label: "试卷名称",
+                        prop: "examName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入试卷名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "试卷分数",
+                        prop: "totalScore",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+                        rules: [{ validator: validatePass, required: true, trigger: 'blur' }],
+                        width: 100
+                    },
+                    {
+                        label: "考试时间",
+                        prop: "examTime",
+                        type: "daterange",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        startPlaceholder: '考试开始时间',
+                        endPlaceholder: '考试结束时间',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        // display: false,
+                        hide: true,
+                        rules: [{
+                            required: true,
+                            message: "请选择考试时间",
+                            trigger: "blur"
+                        }],
+                        width: 250
+                    },
+                    {
+                        label: "考试开始时间",
+                        prop: "startTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 180
+                    },
+                    {
+                        label: "考试结束时间",
+                        prop: "endTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 180
+                    },
+                    {
+                        label: "创建人",
+                        prop: "creator",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: true,
+                        // 表单新增时是否可见
+                        addDisplay: false,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: false,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        hide: true,
+                        display: false,
+                    },
+                    {
+                        label: "备注",
+                        prop: "remark",
+                        span: 24,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false
+                    },
+                    {
+                        label: "注意事项",
+                        prop: "examAttention",
+                        type: "textarea",
+                        span: 24,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        width: 240
+                    },
+
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+    computed: {
+        ids () {
+            let ids = [];
+            this.questionBankSelectionList.forEach(ele => {
+                ids.push(ele.id);
+            });
+            return ids.join(",");
+        },
+    },
+    watch: {
+
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getList(page.currentPage, page.pageSize, Object.assign(params, this.questionBankQuery)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        startExam (row) {
+            this.$router.push({
+                path: `/startexam/${row.id}`,
+                query: row
+            })
+        }
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>
diff --git a/src/views/exam/subject.vue b/src/views/exam/subject.vue
new file mode 100644
index 0000000..cac637c
--- /dev/null
+++ b/src/views/exam/subject.vue
@@ -0,0 +1,263 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 16:04:26
+ * menu-name 题库查询
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-del="questionBankHandleDel">
+
+                        <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="small"
+                                       icon="el-icon-delete"
+                                       @click="questionBankHandleDelete">删 除
+                            </el-button>
+                        </template>
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+import {
+    getList,
+    remove,
+} from "@/api/examapi/subject";
+
+
+export default {
+    data () {
+        return {
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: true,
+
+                editBtn: false,
+
+                addBtn: false,
+
+                selection: true,
+                menu: true,
+                // 导出按钮
+                excelBtn: true,
+                excelBtnText: '题库导出',
+                title: '题库',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                viewBtn: true,
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menuWidth: 226,
+
+                column: [
+                    {
+                        label: "题目名称",
+                        prop: "subjectName",
+                        search: true,
+                        slot: true,
+                    },
+                    {
+                        label: "题目类型",
+                        prop: "choicesType",
+                        search: true,
+                        type: "select",
+                        dicData: [{
+                            label: '单选题',
+                            value: 0
+                        }, {
+                            label: '多选题',
+                            value: 1,
+                        }, {
+                            label: '判断题',
+                            value: 2,
+                        }],
+                        slot: true,
+                        width: 96,
+                    },
+                    {
+                        label: "题目分值",
+                        prop: "score",
+                        slot: true,
+                        width: 96,
+                    },
+                    {
+                        label: "参考答案",
+                        prop: "answer",
+                        slot: true,
+                        width: 96,
+                    },
+                    {
+                        label: "创建人",
+                        prop: "creator",
+                        slot: true,
+                        width: 96,
+                    },
+                    {
+                        label: "创建时间",
+                        prop: "createDate",
+                        slot: true,
+                        width: 130,
+                    },
+                    {
+                        label: "修改人",
+                        prop: "modifier",
+                        slot: true,
+                        width: 96,
+                    },
+                    {
+                        label: "修改时间",
+                        prop: "modifyDate",
+                        slot: true,
+                        width: 130,
+                    }
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+     computed: {
+        ids () {
+            let ids = [];
+            this.questionBankSelectionList.forEach(ele => {
+                ids.push(ele.id);
+            });
+            return ids.join(",");
+        },
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        questionBankHandleDel (row) {
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(row.id);
+                })
+                .then(() => {
+
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                });
+        },
+
+        questionBankHandleDelete () {
+            if (this.questionBankSelectionList.length === 0) {
+                this.$message.warning("请选择至少一条数据");
+                return;
+            }
+            this.$confirm("确定将选择数据删除?", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning"
+            })
+                .then(() => {
+                    return remove(this.ids);
+                })
+                .then(() => {
+                    this.questionBankOnLoad(this.questionBankPage);
+                    this.$message({
+                        type: "success",
+                        message: "操作成功!"
+                    });
+                    this.$refs.questionBankCrud.toggleSelection();
+                });
+        },
+
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/views/exam/topicDetails.vue b/src/views/exam/topicDetails.vue
new file mode 100644
index 0000000..ddbe726
--- /dev/null
+++ b/src/views/exam/topicDetails.vue
@@ -0,0 +1,211 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-13 11:19:28
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-15 16:40:40
+ */
+<template>
+    <div class="app-container">
+
+        <el-tabs v-model="activeName"
+                 @tab-click="handleClick">
+            <el-tab-pane label="单选题"
+                         name="first">
+
+                <div>
+
+                    <el-row>
+                        <el-col :span="12">
+                        </el-col>
+                    </el-row>
+
+                </div>
+
+                <avue-form v-model="form"
+                           :option="option">
+
+                    <template slot-scope="scope"
+                              slot="text">
+                        <div>
+                            <el-input v-model="form.text"
+                                      placeholder="这里是自定的表单"></el-input>
+                        </div>
+                    </template>
+
+                    <template slot-scope="scope"
+                              slot="rate">
+                        <div>
+                            <avue-rate v-model="form.rate"></avue-rate>
+
+                        </div>
+                    </template>
+
+                    <template slot="provinceType"
+                              slot-scope="{item,value,label}">
+                        <span>{{ item }}</span>
+                    </template>
+
+                </avue-form>
+
+            </el-tab-pane>
+            <el-tab-pane label="多选题"
+                         name="second">多选题</el-tab-pane>
+            <el-tab-pane label="判断题"
+                         name="third">判断题</el-tab-pane>
+        </el-tabs>
+    </div>
+</template>
+
+<script>
+export default {
+    data () {
+        return {
+            activeName: 'first',
+
+            rateObj: {
+                state: '一般',
+                value: 4
+            },
+
+            tempSubject: {
+
+            },
+            dialogStatus: '',
+            dialogStatusType: {
+
+            },
+            subjectsType:
+                '',
+            form: {
+                text: '',
+                rate: 4
+            },
+            option: {
+                labelWidth: 120,
+                column: [
+                    {
+                        label: '分值',
+                        prop: 'text',
+                        formslot: true,
+                        labelslot: true,
+                        errorslot: true,
+                        rules: [{
+                            required: true,
+                            message: "请输入姓名",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: '难度',
+                        prop: 'rate',
+                        formslot: true,
+                        labelslot: true,
+                    },
+                    {
+                        label: "参考答案",
+                        prop: "sex",
+                        span: 6,
+                        type: "radio",
+                        dicData: [{
+                            label: 'A',
+                            value: 0
+                        }, {
+                            label: 'B',
+                            value: 1
+                        }, {
+                            label: 'C',
+                            value: 2
+                        }, {
+                            label: 'D',
+                            value: 3
+                        }],
+                        errorslot: true,
+                        rules: [{
+                            required: true,
+                            message: "请选择答案",
+                            trigger: "blur"
+                        }],
+                        mock: {
+                            type: 'dic'
+                        }
+                    },
+                    {
+                        type: 'ueditor',
+                        component: 'AvueUeditor',
+                        label: '题目名称',
+                        span: 24,
+                        display: true,
+                        action: '',
+                        oss: '',
+                        props: {},
+                        ali: {},
+                        qiniu: {},
+                        prop: 'titleName',
+                        rules: [{
+                            required: true,
+                            message: "请输入题目名称",
+                            trigger: "blur"
+                        }],
+                    },
+                    {
+                        label: '',
+                        labelWidth: 40,
+                        prop: 'divider',
+                        component: 'elDivider',//ele分割线
+                        span: 24,
+                        event: {
+                            click: () => {
+                                this.$message.success('点击方法')
+                            },
+                        },
+                        params: {
+                            html: '<h2 style="font-size: 16px; font-weight: normal"> 选项列表 </h2>',
+                            contentPosition: "center",
+                        }
+                    },
+                    {
+                        label: "题目名称",
+                        prop: "content",
+                        component: 'AvueUeditor',
+                        options: {
+                            action: '/api/blade-resource/oss/endpoint/put-file',
+                            props: {
+                                res: "data",
+                                url: "link",
+                            }
+                        },
+                        hide: true,
+                        minRows: 6,
+                        span: 24,
+                        rules: [{
+                            required: true,
+                            message: "请输入题目名称",
+                            trigger: "blur"
+                        }],
+                    }
+                ]
+            }
+        }
+    },
+    methods: {
+        handleTabChange () { },
+        handleSelectSubject () { },
+        dialogSubjectFormVisible () { },
+        createSubjectData () { },
+        updateSubjectData () { },
+        updateAndAddSubjectData () { },
+        handleClick (tab, event) {
+            console.log(tab, event);
+        }
+
+    }
+}
+
+</script>
+
+
+<style lang="scss" scoped>
+.dialog-footer {
+    margin-top: 20px;
+}
+</style>
diff --git a/src/views/recruitmentManagement/index.vue b/src/views/recruitmentManagement/index.vue
index 49b668b..a2ce3dd 100644
--- a/src/views/recruitmentManagement/index.vue
+++ b/src/views/recruitmentManagement/index.vue
@@ -56,7 +56,7 @@
         viewBtn: true,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 627,
+        height: 693,
         menuWidth: 210,
         align: "center",
         selection: true,
diff --git a/src/views/resource/attach.vue b/src/views/resource/attach.vue
index 29abbf0..763c1ba 100644
--- a/src/views/resource/attach.vue
+++ b/src/views/resource/attach.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="hasButTwo">
     <avue-crud
       :option="option"
       :table-loading="loading"
diff --git a/src/views/resource/oss.vue b/src/views/resource/oss.vue
index f51480e..6bbccf1 100644
--- a/src/views/resource/oss.vue
+++ b/src/views/resource/oss.vue
@@ -1,415 +1,457 @@
 <template>
-  <basic-container>
-    <avue-crud :option="option"
-               :table-loading="loading"
-               :data="data"
-               :page.sync="page"
-               :permission="permissionList"
-               v-model="form"
-               ref="crud"
-               @row-update="rowUpdate"
-               @row-save="rowSave"
-               @row-del="rowDel"
-               :before-open="beforeOpen"
-               @search-change="searchChange"
-               @search-reset="searchReset"
-               @selection-change="selectionChange"
-               @current-change="currentChange"
-               @size-change="sizeChange"
-               @refresh-change="refreshChange"
-               @on-load="onLoad">
+  <basic-container class="hasButOne">
+    <avue-crud
+      :option="option"
+      :table-loading="loading"
+      :data="data"
+      :page.sync="page"
+      :permission="permissionList"
+      v-model="form"
+      ref="crud"
+      @row-update="rowUpdate"
+      @row-save="rowSave"
+      @row-del="rowDel"
+      :before-open="beforeOpen"
+      @search-change="searchChange"
+      @search-reset="searchReset"
+      @selection-change="selectionChange"
+      @current-change="currentChange"
+      @size-change="sizeChange"
+      @refresh-change="refreshChange"
+      @on-load="onLoad"
+    >
       <template slot="menuLeft">
-        <el-button type="danger"
-                   size="small"
-                   icon="el-icon-delete"
-                   plain
-                   v-if="permission.oss_delete"
-                   @click="handleDelete">删 除
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          plain
+          v-if="permission.oss_delete"
+          @click="handleDelete"
+          >删 除
         </el-button>
       </template>
       <template slot-scope="scope" slot="menu">
-        <el-button type="text"
-                   icon="el-icon-video-play"
-                   size="small"
-                   v-if="userInfo.role_name.includes('admin')"
-                   @click="handleDebug(scope.row)">调试
+        <el-button
+          type="text"
+          icon="el-icon-video-play"
+          size="small"
+          v-if="userInfo.role_name.includes('admin')"
+          @click="handleDebug(scope.row)"
+          >调试
         </el-button>
-        <el-button type="text"
-                   icon="el-icon-circle-check"
-                   size="small"
-                   v-if="permission.oss_enable"
-                   @click.stop="handleEnable(scope.row)">启用
+        <el-button
+          type="text"
+          icon="el-icon-circle-check"
+          size="small"
+          v-if="permission.oss_enable"
+          @click.stop="handleEnable(scope.row)"
+          >启用
         </el-button>
       </template>
-      <template slot-scope="{row}"
-                slot="status">
-        <el-tag>{{row.statusName}}</el-tag>
+      <template slot-scope="{ row }" slot="status">
+        <el-tag>{{ row.statusName }}</el-tag>
       </template>
-      <template slot-scope="{row}"
-                slot="category">
-        <el-tag>{{row.categoryName}}</el-tag>
+      <template slot-scope="{ row }" slot="category">
+        <el-tag>{{ row.categoryName }}</el-tag>
       </template>
     </avue-crud>
-    <el-dialog title="对象存储上传调试"
-               append-to-body
-               :visible.sync="box"
-               width="550px">
-      <avue-form ref="form" :option="debugOption" v-model="debugForm" @submit="handleSubmit"/>
+    <el-dialog
+      title="对象存储上传调试"
+      append-to-body
+      :visible.sync="box"
+      width="550px"
+    >
+      <avue-form
+        ref="form"
+        :option="debugOption"
+        v-model="debugForm"
+        @submit="handleSubmit"
+      />
     </el-dialog>
   </basic-container>
 </template>
 
 <script>
-  import {getList, getDetail, add, update, remove, enable} from "@/api/resource/oss";
-  import {mapGetters} from "vuex";
-  import func from "@/util/func";
+import {
+  getList,
+  getDetail,
+  add,
+  update,
+  remove,
+  enable,
+} from "@/api/resource/oss";
+import { mapGetters } from "vuex";
+import func from "@/util/func";
 
-  export default {
-    data() {
-      return {
-        form: {},
-        query: {},
-        loading: true,
-        box: false,
-        page: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0
-        },
-        selectionList: [],
-        option: {
-          height: 'auto',
-          calcHeight: 30,
-          tip: false,
-          searchShow: true,
-          searchMenuSpan: 6,
-          border: true,
-          index: true,
-          viewBtn: true,
-          selection: true,
-          menuWidth: 300,
-          labelWidth: 100,
-          dialogWidth: 880,
-          dialogClickModal: false,
-          column: [
-            {
-              label: "分类",
-              type: "radio",
-              value: 1,
-              span: 24,
-              width: 100,
-              searchLabelWidth: 50,
-              row: true,
-              dicUrl: "/api/blade-system/dict/dictionary?code=oss",
-              props: {
-                label: "dictValue",
-                value: "dictKey"
-              },
-              dataType: "number",
-              slot: true,
-              prop: "category",
-              search: true,
-              rules: [{
+export default {
+  data() {
+    return {
+      form: {},
+      query: {},
+      loading: true,
+      box: false,
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0,
+      },
+      selectionList: [],
+      option: {
+        height: "auto",
+        calcHeight: 30,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 6,
+        border: true,
+        index: true,
+        viewBtn: true,
+        selection: true,
+        menuWidth: 300,
+        labelWidth: 100,
+        dialogWidth: 880,
+        dialogClickModal: false,
+        column: [
+          {
+            label: "分类",
+            type: "radio",
+            value: 1,
+            span: 24,
+            width: 100,
+            searchLabelWidth: 50,
+            row: true,
+            dicUrl: "/api/blade-system/dict/dictionary?code=oss",
+            props: {
+              label: "dictValue",
+              value: "dictKey",
+            },
+            dataType: "number",
+            slot: true,
+            prop: "category",
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请选择分类",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "资源编号",
-              prop: "ossCode",
-              span: 24,
-              width: 120,
-              search: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "资源编号",
+            prop: "ossCode",
+            span: 24,
+            width: 120,
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入资源编号",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "资源地址",
-              prop: "endpoint",
-              span: 24,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "资源地址",
+            prop: "endpoint",
+            span: 24,
+            rules: [
+              {
                 required: true,
                 message: "请输入资源地址",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "空间名",
-              prop: "bucketName",
-              span: 24,
-              width: 120,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "空间名",
+            prop: "bucketName",
+            span: 24,
+            width: 120,
+            rules: [
+              {
                 required: true,
                 message: "请输入空间名",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "accessKey",
-              prop: "accessKey",
-              span: 24,
-              search: true,
-              width: 200,
-              overHidden: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "accessKey",
+            prop: "accessKey",
+            span: 24,
+            search: true,
+            width: 200,
+            overHidden: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入accessKey",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "secretKey",
-              prop: "secretKey",
-              span: 24,
-              width: 200,
-              overHidden: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "secretKey",
+            prop: "secretKey",
+            span: 24,
+            width: 200,
+            overHidden: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入secretKey",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "appId",
-              prop: "appId",
-              span: 24,
-              hide: true,
-              display: false,
-            },
-            {
-              label: "region",
-              prop: "region",
-              span: 24,
-              hide: true,
-              display: false,
-            },
-            {
-              label: "是否启用",
-              prop: "status",
-              span: 24,
-              width: 80,
-              align: "center",
-              slot: true,
-              addDisplay: false,
-              editDisplay: false,
-              viewDisplay: false,
-            },
-            {
-              label: "备注",
-              prop: "remark",
-              span: 24,
-              hide: true,
-            },
-          ]
-        },
-        data: [],
-        debugForm: {
-          code: '',
-        },
-        debugOption: {
-          submitText: "提交",
-          column: [
-            {
-              label: "资源编号",
-              prop: "code",
-              disabled: true,
-              span: 24,
-            },
-            {
-              label: "上传背景",
-              prop: "backgroundUrl",
-              type: 'upload',
-              listType: 'picture-img',
-              action: '/api/blade-resource/oss/endpoint/put-file',
-              propsHttp: {
-                res: 'data',
-                url: 'link',
+                trigger: "blur",
               },
-              span: 24,
+            ],
+          },
+          {
+            label: "appId",
+            prop: "appId",
+            span: 24,
+            hide: true,
+            display: false,
+          },
+          {
+            label: "region",
+            prop: "region",
+            span: 24,
+            hide: true,
+            display: false,
+          },
+          {
+            label: "是否启用",
+            prop: "status",
+            span: 24,
+            width: 80,
+            align: "center",
+            slot: true,
+            addDisplay: false,
+            editDisplay: false,
+            viewDisplay: false,
+          },
+          {
+            label: "备注",
+            prop: "remark",
+            span: 24,
+            hide: true,
+          },
+        ],
+      },
+      data: [],
+      debugForm: {
+        code: "",
+      },
+      debugOption: {
+        submitText: "提交",
+        column: [
+          {
+            label: "资源编号",
+            prop: "code",
+            disabled: true,
+            span: 24,
+          },
+          {
+            label: "上传背景",
+            prop: "backgroundUrl",
+            type: "upload",
+            listType: "picture-img",
+            action: "/api/blade-resource/oss/endpoint/put-file",
+            propsHttp: {
+              res: "data",
+              url: "link",
             },
-          ]
+            span: 24,
+          },
+        ],
+      },
+    };
+  },
+  watch: {
+    "form.category"() {
+      const category = func.toInt(this.form.category);
+      this.$refs.crud.option.column.filter((item) => {
+        if (item.prop === "appId") {
+          item.display = category === 4;
         }
+        if (item.prop === "region") {
+          item.display = category === 4;
+        }
+      });
+    },
+    "debugForm.code"() {
+      const column = this.findObject(this.debugOption.column, "backgroundUrl");
+      column.action = `/api/blade-resource/oss/endpoint/put-file?code=${this.debugForm.code}`;
+    },
+  },
+  computed: {
+    ...mapGetters(["userInfo", "permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission.oss_add),
+        viewBtn: this.vaildData(this.permission.oss_view),
+        delBtn: this.vaildData(this.permission.oss_delete),
+        editBtn: this.vaildData(this.permission.oss_edit),
       };
     },
-    watch: {
-      'form.category'() {
-        const category = func.toInt(this.form.category);
-        this.$refs.crud.option.column.filter(item => {
-          if (item.prop === "appId") {
-            item.display = category === 4;
-          }
-          if (item.prop === "region") {
-            item.display = category === 4;
-          }
-        });
-      },
-      'debugForm.code'() {
-        const column = this.findObject(this.debugOption.column, "backgroundUrl");
-        column.action = `/api/blade-resource/oss/endpoint/put-file?code=${this.debugForm.code}`;
-      }
+    ids() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
     },
-    computed: {
-      ...mapGetters(["userInfo", "permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.oss_add),
-          viewBtn: this.vaildData(this.permission.oss_view),
-          delBtn: this.vaildData(this.permission.oss_delete),
-          editBtn: this.vaildData(this.permission.oss_edit)
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
-      }
-    },
-    methods: {
-      rowSave(row, done, loading) {
-        add(row).then(() => {
+  },
+  methods: {
+    rowSave(row, done, loading) {
+      add(row).then(
+        () => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowUpdate(row, index, done, loading) {
-        update(row).then(() => {
+        }
+      );
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(
+        () => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowDel(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      searchReset() {
-        this.query = {};
-        this.onLoad(this.page);
-      },
-      searchChange(params, done) {
-        this.query = params;
-        this.page.currentPage = 1;
-        this.onLoad(this.page, params);
-        done();
-      },
-      selectionChange(list) {
-        this.selectionList = list;
-      },
-      selectionClear() {
-        this.selectionList = [];
-        this.$refs.crud.toggleSelection();
-      },
-      handleEnable(row) {
-        this.$confirm("是否确定启用这条配置?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return enable(row.id);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crud.toggleSelection();
-          });
-      },
-      handleDebug(row) {
-        this.box = true;
-        this.debugForm.code = row.ossCode;
-        this.debugForm.backgroundUrl = '';
-      },
-      handleSubmit(form, done) {
-        this.$message({
-          type: "success",
-          message: `获取到图片地址:[${form.backgroundUrl}]`
-        });
-        done();
-      },
-      handleDelete() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
         }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
+      );
+    },
+    rowDel(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
         })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crud.toggleSelection();
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
           });
-      },
-      beforeOpen(done, type) {
-        if (["edit", "view"].includes(type)) {
-          getDetail(this.form.id).then(res => {
-            this.form = res.data.data;
+        });
+    },
+    searchReset() {
+      this.query = {};
+      this.onLoad(this.page);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    handleEnable(row) {
+      this.$confirm("是否确定启用这条配置?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return enable(row.id);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
           });
-        }
-        done();
-      },
-      currentChange(currentPage) {
-        this.page.currentPage = currentPage;
-      },
-      sizeChange(pageSize) {
-        this.page.pageSize = pageSize;
-      },
-      refreshChange() {
-        this.onLoad(this.page, this.query);
-      },
-      onLoad(page, params = {}) {
-        this.loading = true;
-        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
-          const data = res.data.data;
-          this.page.total = data.total;
-          this.data = data.records;
-          this.loading = false;
-          this.selectionClear();
+          this.$refs.crud.toggleSelection();
+        });
+    },
+    handleDebug(row) {
+      this.box = true;
+      this.debugForm.code = row.ossCode;
+      this.debugForm.backgroundUrl = "";
+    },
+    handleSubmit(form, done) {
+      this.$message({
+        type: "success",
+        message: `获取到图片地址:[${form.backgroundUrl}]`,
+      });
+      done();
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.$refs.crud.toggleSelection();
+        });
+    },
+    beforeOpen(done, type) {
+      if (["edit", "view"].includes(type)) {
+        getDetail(this.form.id).then((res) => {
+          this.form = res.data.data;
         });
       }
-    }
-  };
+      done();
+    },
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoad(this.page, this.query);
+    },
+    onLoad(page, params = {}) {
+      this.loading = true;
+      getList(
+        page.currentPage,
+        page.pageSize,
+        Object.assign(params, this.query)
+      ).then((res) => {
+        const data = res.data.data;
+        this.page.total = data.total;
+        this.data = data.records;
+        this.loading = false;
+        this.selectionClear();
+      });
+    },
+  },
+};
 </script>
diff --git a/src/views/securityEquipment/car.vue b/src/views/securityEquipment/car.vue
index 51306fc..7443bdb 100644
--- a/src/views/securityEquipment/car.vue
+++ b/src/views/securityEquipment/car.vue
@@ -48,9 +48,10 @@
       option: {
         // card: true,
         tip: false,
+        index: true,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 627,
+        height: 693,
         menuWidth: 160,
         align: "center",
         selection: true,
diff --git a/src/views/securityEquipment/equipments.vue b/src/views/securityEquipment/equipments.vue
index ba983e0..71f70a3 100644
--- a/src/views/securityEquipment/equipments.vue
+++ b/src/views/securityEquipment/equipments.vue
@@ -50,7 +50,8 @@
         tip: false,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 627,
+        height: 693,
+        index: true,
         menuWidth: 160,
         align: "center",
         selection: true,
diff --git a/src/views/securityEquipment/gun.js b/src/views/securityEquipment/gun.js
index ab9b0c1..885be6c 100644
--- a/src/views/securityEquipment/gun.js
+++ b/src/views/securityEquipment/gun.js
@@ -14,11 +14,13 @@
         prop: "id",
         hide: true,
         editDisplay: false,
-        addDisplay: false
+        addDisplay: false,
+        labelWidth: 160,
     },
     {
         label: "公务用枪证编号",
         prop: "gunCardNumber",
+        labelWidth: 160,
         searchLabelWidth: 130,
         search: true,
         rules: [{
@@ -30,6 +32,7 @@
     {
         label: "发证单位名称",
         searchLabelWidth: 110,
+        labelWidth: 160,
         prop: "issueUnit",
         rules: [{
             required: true,
@@ -41,6 +44,7 @@
     {
         label: "公务用枪编号",
         prop: "cardNumber",
+        labelWidth: 160,
         searchLabelWidth: 110,
         rules: [{
             required: true,
@@ -53,6 +57,7 @@
         label: "枪型",
         prop: "gunMode",
         width: 70,
+        labelWidth: 160,
         rules: [{
             required: true,
             message: "请输入枪型",
@@ -63,6 +68,7 @@
     {
         label: "保安公司",
         prop: "tenantName",
+        labelWidth: 160,
         rules: [{
             required: true,
             message: "请输入组织机构",
@@ -89,6 +95,7 @@
     {
         label: "责任人",
         prop: "personInCharge",
+        labelWidth: 160,
         rules: [{
             required: true,
             message: "请输入责任人",
@@ -97,6 +104,7 @@
     },
     {
         label: "发证日期",
+        labelWidth: 160,
         prop: "issueTime",
         // search: true,
         type: "date",
@@ -114,6 +122,7 @@
     {
         label: "有效日期",
         prop: "validTime",
+        labelWidth: 160,
         // search: true,
         type: "date",
         format: "yyyy-MM-dd",
diff --git a/src/views/securityEquipment/gun.vue b/src/views/securityEquipment/gun.vue
index 022668d..e12b2d7 100644
--- a/src/views/securityEquipment/gun.vue
+++ b/src/views/securityEquipment/gun.vue
@@ -50,7 +50,8 @@
         tip: false,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 627,
+        height: 693,
+        index: true,
         menuWidth: 160,
         align: "center",
         selection: true,
diff --git a/src/views/securityGuard/data.js b/src/views/securityGuard/data.js
index 2776d06..be42d52 100644
--- a/src/views/securityGuard/data.js
+++ b/src/views/securityGuard/data.js
@@ -1,314 +1,314 @@
 //保安员基本信息
 export var securityBaseInfoColumn = [{
-        label: "",
-        labelWidth: "20",
-        type: 'title',
-        prop: "title",
-        span: 24,
-        styles: {
-            fontSize: '24px'
-        }
-    },
-    {
-        label: "所属保安公司",
-        prop: "deptId",
-        type: "tree",
-        dicUrl: "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
-        // dicUrl: "/api/blade-system/dept/lazy-tree?parentId=0",
-        props: {
-            label: "title",
-            value: "id",
-        },
-        disabled: true,
-        span: 24,
-    },
-    {
-        label: "登录账号",
-        prop: "account",
-        disabled: true
-    },
-    {
-        label: "用户姓名",
-        prop: "realName",
-        disabled: true,
-    },
-    {
-        label: "用户昵称",
-        prop: "name",
-        disabled: true
-    },
-    {
-        label: "手机号码",
-        prop: "phone",
-        disabled: true
-    },
-    {
-        label: "电子邮箱",
-        prop: "email",
-        disabled: true
-    },
-    {
-        label: "身份证号",
-        prop: "cardid",
-        disabled: true
-    },
-    {
-        label: "籍贯",
-        prop: "nativeplace",
-        disabled: true
-    },
-    {
-        label: "民族",
-        prop: "nation",
-        disabled: true
-    },
-    {
-        label: "是否持证",
-        prop: "hold",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=equipage",
-        props: {
-            label: "dictValue",
-            value: "dictKey",
-        },
-        type: "select",
-        disabled: true
-    },
-    {
-        label: "保安员证编号",
-        prop: "securitynumber",
-        disabled: true
-    },
-    {
-        label: "所属辖区",
-        prop: "jurisdiction",
-        // multiple: true,
-        type: "tree",
-        dicUrl: "/api/jurisdiction/lazy-tree?parentId=0",
-        props: {
-            label: "title",
-            value: "id",
-        },
-        disabled: true
-    },
-    {
-        label: "最高学历",
-        prop: "education",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        slot: true,
-        disabled: true
-    },
-    {
-        label: "政治面貌",
-        prop: "politicaloutlook",
-        disabled: true
-    },
-    {
-        label: "身高",
-        prop: "height",
-        disabled: true
-    },
-    {
-        label: "联系地址",
-        prop: "address",
-        disabled: true
-    },
-    {
-        label: "户口所在地",
-        prop: "registered",
-        disabled: true
-    },
-    {
-        label: "入职时间",
-        prop: "rtime",
-        type: 'date',
-        format: "yyyy-MM-dd",
-        valueFormat: "yyyy-MM-dd",
-        disabled: true
-    },
-    {
-        label: "用户性别",
-        prop: "sex",
-        type: "select",
-        dicData: [{
-                label: "男",
-                value: 1
-            },
-            {
-                label: "女",
-                value: 2
-            },
-            {
-                label: "未知",
-                value: 3
-            }
-        ],
-        disabled: true
-    },
-    {
-        label: "用户生日",
-        type: "date",
-        prop: "birthday",
-        disabled: true
+    label: "",
+    labelWidth: "20",
+    type: 'title',
+    prop: "title",
+    span: 24,
+    styles: {
+        fontSize: '24px'
     }
+},
+{
+    label: "所属保安公司",
+    prop: "deptId",
+    type: "tree",
+    dicUrl: "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
+    // dicUrl: "/api/blade-system/dept/lazy-tree?parentId=0",
+    props: {
+        label: "title",
+        value: "id",
+    },
+    disabled: true,
+    span: 24,
+},
+{
+    label: "登录账号",
+    prop: "account",
+    disabled: true
+},
+{
+    label: "用户姓名",
+    prop: "realName",
+    disabled: true,
+},
+{
+    label: "用户昵称",
+    prop: "name",
+    disabled: true
+},
+{
+    label: "手机号码",
+    prop: "phone",
+    disabled: true
+},
+{
+    label: "电子邮箱",
+    prop: "email",
+    disabled: true
+},
+{
+    label: "身份证号",
+    prop: "cardid",
+    disabled: true
+},
+{
+    label: "籍贯",
+    prop: "nativeplace",
+    disabled: true
+},
+{
+    label: "民族",
+    prop: "nation",
+    disabled: true
+},
+{
+    label: "是否持证",
+    prop: "hold",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=equipage",
+    props: {
+        label: "dictValue",
+        value: "dictKey",
+    },
+    type: "select",
+    disabled: true
+},
+{
+    label: "保安员证编号",
+    prop: "securitynumber",
+    disabled: true
+},
+{
+    label: "所属辖区",
+    prop: "jurisdiction",
+    // multiple: true,
+    type: "tree",
+    dicUrl: "/api/jurisdiction/lazy-tree?parentId=0",
+    props: {
+        label: "title",
+        value: "id",
+    },
+    disabled: true
+},
+{
+    label: "最高学历",
+    prop: "education",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
+    },
+    dataType: "number",
+    slot: true,
+    disabled: true
+},
+{
+    label: "政治面貌",
+    prop: "politicaloutlook",
+    disabled: true
+},
+{
+    label: "身高",
+    prop: "height",
+    disabled: true
+},
+{
+    label: "联系地址",
+    prop: "address",
+    disabled: true
+},
+{
+    label: "户口所在地",
+    prop: "registered",
+    disabled: true
+},
+{
+    label: "入职时间",
+    prop: "rtime",
+    type: 'date',
+    format: "yyyy-MM-dd",
+    valueFormat: "yyyy-MM-dd",
+    disabled: true
+},
+{
+    label: "用户性别",
+    prop: "sex",
+    type: "select",
+    dicData: [{
+        label: "男",
+        value: 1
+    },
+    {
+        label: "女",
+        value: 2
+    },
+    {
+        label: "未知",
+        value: 3
+    }
+    ],
+    disabled: true
+},
+{
+    label: "用户生日",
+    type: "date",
+    prop: "birthday",
+    disabled: true
+}
 
 
 ]
 
 
 export var securityBaseInfoColumns = [{
-        label: "所属保安单位",
-        prop: "tenantId",
-        type: "tree",
-        dicUrl: "/api/blade-system/tenant/select",
-        props: {
-            label: "tenantName",
-            value: "tenantId"
-        },
-        disabled: true,
-        span: 24,
+    label: "所属保安单位",
+    prop: "tenantId",
+    type: "tree",
+    dicUrl: "/api/blade-system/tenant/select",
+    props: {
+        label: "tenantName",
+        value: "tenantId"
+    },
+    disabled: true,
+    span: 24,
+},
+{
+    label: "登录账号",
+    prop: "account",
+    disabled: true
+},
+{
+    label: "用户姓名",
+    prop: "realName",
+    rules: [{
+        required: true,
+        message: "请输入用户姓名",
+        trigger: "blur"
+    }, {
+        min: 2,
+        max: 5,
+        message: '姓名长度在2到5个字符'
+    }]
+},
+{
+    label: "用户昵称",
+    prop: "name"
+},
+{
+    label: "手机号码",
+    prop: "phone",
+    overHidden: true,
+    rules: [{
+        required: true,
+        message: "请输入手机号",
+        trigger: "blur"
+    }]
+},
+{
+    label: "电子邮箱",
+    prop: "email",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "身份证号",
+    prop: "cardid",
+    hide: true,
+    overHidden: true,
+    rules: [{
+        required: true,
+        message: "请输入身份证号",
+        trigger: "blur"
+    }]
+},
+{
+    label: "籍贯",
+    prop: "nativeplace",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "民族",
+    prop: "nation",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "最高学历",
+    prop: "education",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
+    },
+    dataType: "number",
+    slot: true,
+    rules: [{
+        required: true,
+        message: "请选择学历",
+        trigger: "blur"
+    }]
+},
+{
+    label: "政治面貌",
+    prop: "politicaloutlook",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "身高",
+    prop: "height",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "联系地址",
+    prop: "address",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "户口所在地",
+    prop: "registered",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "入职时间",
+    prop: "rtime",
+    type: 'date',
+    format: "yyyy-MM-dd",
+    valueFormat: "yyyy-MM-dd",
+    hide: true,
+    overHidden: true
+},
+{
+    label: "用户性别",
+    prop: "sex",
+    type: "select",
+    dicData: [{
+        label: "男",
+        value: 1
     },
     {
-        label: "登录账号",
-        prop: "account",
-        disabled: true
+        label: "女",
+        value: 2
     },
     {
-        label: "用户姓名",
-        prop: "realName",
-        rules: [{
-            required: true,
-            message: "请输入用户姓名",
-            trigger: "blur"
-        }, {
-            min: 2,
-            max: 5,
-            message: '姓名长度在2到5个字符'
-        }]
-    },
-    {
-        label: "用户昵称",
-        prop: "name"
-    },
-    {
-        label: "手机号码",
-        prop: "phone",
-        overHidden: true,
-        rules: [{
-            required: true,
-            message: "请输入手机号",
-            trigger: "blur"
-        }]
-    },
-    {
-        label: "电子邮箱",
-        prop: "email",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "身份证号",
-        prop: "cardid",
-        hide: true,
-        overHidden: true,
-        rules: [{
-            required: true,
-            message: "请输入身份证号",
-            trigger: "blur"
-        }]
-    },
-    {
-        label: "籍贯",
-        prop: "nativeplace",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "民族",
-        prop: "nation",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "最高学历",
-        prop: "education",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        slot: true,
-        rules: [{
-            required: true,
-            message: "请选择学历",
-            trigger: "blur"
-        }]
-    },
-    {
-        label: "政治面貌",
-        prop: "politicaloutlook",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "身高",
-        prop: "height",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "联系地址",
-        prop: "address",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "户口所在地",
-        prop: "registered",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "入职时间",
-        prop: "rtime",
-        type: 'date',
-        format: "yyyy-MM-dd",
-        valueFormat: "yyyy-MM-dd",
-        hide: true,
-        overHidden: true
-    },
-    {
-        label: "用户性别",
-        prop: "sex",
-        type: "select",
-        dicData: [{
-                label: "男",
-                value: 1
-            },
-            {
-                label: "女",
-                value: 2
-            },
-            {
-                label: "未知",
-                value: 3
-            }
-        ],
-        hide: true
-    },
-    {
-        label: "用户生日",
-        type: "date",
-        prop: "birthday",
-        hide: true
+        label: "未知",
+        value: 3
     }
+    ],
+    hide: true
+},
+{
+    label: "用户生日",
+    type: "date",
+    prop: "birthday",
+    hide: true
+}
 ]
 
 
@@ -443,153 +443,153 @@
 
 
 export var securityFormPageColumn = [{
-        label: "姓名",
-        prop: "realName",
-        search: true,
-        searchSpan: 4,
-        display: false
+    label: "姓名",
+    prop: "realName",
+    search: true,
+    searchSpan: 4,
+    display: false
+},
+{
+    label: "性别",
+    prop: "sex",
+    type: "select",
+    dicData: [{
+        label: "男",
+        value: 1,
     },
     {
-        label: "性别",
-        prop: "sex",
-        type: "select",
-        dicData: [{
-                label: "男",
-                value: 1,
-            },
-            {
-                label: "女",
-                value: 2,
-            },
-            {
-                label: "未知",
-                value: 3,
-            },
-        ],
-        display: false
+        label: "女",
+        value: 2,
     },
+    {
+        label: "未知",
+        value: 3,
+    },
+    ],
+    display: false
+},
 
-    {
-        label: "籍贯",
-        prop: "nativeplace",
-        display: false
+{
+    label: "籍贯",
+    prop: "nativeplace",
+    display: false
+},
+{
+    label: "民族",
+    prop: "nation",
+    display: false
+},
+{
+    label: "出生日期",
+    prop: "birthday",
+    type: "date",
+    format: "yyyy-MM-dd",
+    valueFormat: "yyyy-MM-dd",
+    display: false
+},
+{
+    label: "学历",
+    prop: "education",
+    display: false,
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "民族",
-        prop: "nation",
-        display: false
+    type: "select",
+    hide: true,
+    rules: [{
+        required: true,
+        message: "请选择学历",
+        trigger: "blur"
+    }],
+},
+{
+    label: "联系电话",
+    prop: "phone",
+    display: false
+},
+{
+    label: "邮箱",
+    prop: "email",
+    display: false,
+    width: 150
+},
+{
+    label: "入职时间",
+    prop: "rtime",
+    display: false
+},
+{
+    label: "保安公司名称",
+    searchLabelWidth: "110",
+    // prop: "deptName",
+    prop: "deptId",
+    type: "tree",
+    dicUrl: "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
+    props: {
+        label: "title",
+        value: "id",
     },
-    {
-        label: "出生日期",
-        prop: "birthday",
-        type: "date",
-        format: "yyyy-MM-dd",
-        valueFormat: "yyyy-MM-dd",
-        display: false
+    slot: true,
+    searchSpan: 6,
+    display: false,
+    search: true,
+    width: 260
+},
+{
+    label: "是否持证",
+    prop: "hold",
+    slot: true,
+    display: false,
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=equipage",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "学历",
-        prop: "education",
-        display: false,
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=educationType",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        type: "select",
-        hide: true,
-        rules: [{
-            required: true,
-            message: "请选择学历",
-            trigger: "blur"
-        }],
+    type: "select",
+    rules: [{
+        required: true,
+        message: "请选择",
+        trigger: "blur"
+    }],
+},
+// {
+//     label: "入职时间",
+//     prop: "rtime",
+//     type: "datetime",
+//     format: "yyyy-MM-dd",
+//     valueFormat: "yyyy-MM-dd",
+//     searchRange: true,
+//     searchSpan: 6,
+//     hide: true,
+//     addDisplay: false,
+//     editDisplay: false,
+//     viewDisplay: false,
+//     search: true,
+//     rules: [{
+//         required: true,
+//         message: "请输入时间",
+//         trigger: "blur"
+//     }]
+// },
+{
+    label: "在职状态",
+    prop: "status",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=workerState",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "联系电话",
-        prop: "phone",
-        display: false
-    },
-    {
-        label: "邮箱",
-        prop: "email",
-        display: false,
-        width: 150
-    },
-    {
-        label: "入职时间",
-        prop: "rtime",
-        display: false
-    },
-    {
-        label: "保安公司名称",
-        searchLabelWidth: "110",
-        // prop: "deptName",
-        prop: "deptId",
-        type: "tree",
-        dicUrl: "/api/blade-system/dept/security_lazy-tree?parentId=1413470343230877697",
-        props: {
-            label: "title",
-            value: "id",
-        },
-        slot: true,
-        searchSpan: 5,
-        display: false,
-        search: true,
-        width: 260
-    },
-    {
-        label: "是否持证",
-        prop: "hold",
-        slot: true,
-        display: false,
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=equipage",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        type: "select",
-        rules: [{
-            required: true,
-            message: "请选择",
-            trigger: "blur"
-        }],
-    },
-    // {
-    //     label: "入职时间",
-    //     prop: "rtime",
-    //     type: "datetime",
-    //     format: "yyyy-MM-dd",
-    //     valueFormat: "yyyy-MM-dd",
-    //     searchRange: true,
-    //     searchSpan: 6,
-    //     hide: true,
-    //     addDisplay: false,
-    //     editDisplay: false,
-    //     viewDisplay: false,
-    //     search: true,
-    //     rules: [{
-    //         required: true,
-    //         message: "请输入时间",
-    //         trigger: "blur"
-    //     }]
-    // },
-    {
-        label: "在职状态",
-        prop: "status",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=workerState",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        display: false,
-        searchSpan: 3,
-        search: true,
-        rules: [{
-            required: true,
-            message: "请选择在职状态",
-            trigger: "blur"
-        }]
-    },
+    dataType: "number",
+    display: false,
+    searchSpan: 4,
+    search: true,
+    rules: [{
+        required: true,
+        message: "请选择在职状态",
+        trigger: "blur"
+    }]
+},
 ]
\ No newline at end of file
diff --git a/src/views/securityGuard/securityGuard.vue b/src/views/securityGuard/securityGuard.vue
index b1cb3d1..044ae20 100644
--- a/src/views/securityGuard/securityGuard.vue
+++ b/src/views/securityGuard/securityGuard.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-row>
+  <el-row class="securityGuard">
     <el-col :span="0" style="display: none">
       <div class="box">
         <el-scrollbar>
@@ -322,11 +322,12 @@
         searchMenuSpan: 6,
         border: false,
         stripe: true,
+        align: "center",
         index: true,
         delBtnText: "注销",
         selection: true,
         viewBtn: true,
-        defaultExpandAll:true,
+        defaultExpandAll: true,
         //dialogType: 'drawer',
         dialogClickModal: false,
         column: securityFormPageColumn,
diff --git a/src/views/securityUnit/data.js b/src/views/securityUnit/data.js
index f2294a1..b2ed258 100644
--- a/src/views/securityUnit/data.js
+++ b/src/views/securityUnit/data.js
@@ -21,6 +21,8 @@
         prop: "creditcode",
         width: 140,
         hide: true,
+
+        labelWidth: 160,
         // hide: true,
         // editDisplay: false,
         // addDisplay: false
@@ -55,12 +57,15 @@
         label: "企业名称",
         prop: "enterprisename",
         search: true,
+        searchSpan: 6,
+        labelWidth: 160,
         // width: 130,
     },
     {
         label: "企业类型",
         prop: "stats",
         type: "tree",
+        labelWidth: 160,
         dicUrl: "/api/blade-system/dict-biz/dictionary?code=stats",
         props: {
             label: "dictValue",
@@ -77,10 +82,11 @@
     },
     {
         label: "法定代表人",
+        labelWidth: 160,
         prop: "representative",
         width: 80,
         search: true,
-        searchSpan: 5,
+        searchSpan: 6,
         searchLabelWidth: 100
     },
     // {
@@ -106,6 +112,7 @@
     {
         label: "成立日期",
         prop: "establishtime",
+        labelWidth: 160,
         width: 130,
         overHidden: true,
         type: "date",
@@ -131,6 +138,7 @@
     {
         label: "注册资本(万元人民币)",
         prop: "registeredcapital",
+        labelWidth: 160,
         // search: true,
         width: 140,
         // overHidden: true
@@ -138,6 +146,7 @@
     {
         label: "实缴资本(万元人民币)",
         prop: "capital",
+        labelWidth: 160,
         // width: 85,
         hide: true,
         // search: true,
@@ -146,6 +155,7 @@
     },
     {
         label: "组织机构代码",
+        labelWidth: 160,
         prop: "organizationcode",
         // width: 110,
         // search: true,
@@ -154,6 +164,7 @@
     {
         label: "工商注册号",
         prop: "registrationnumber",
+        labelWidth: 160,
         width: 120,
         // search: true,
         // searchSpan: 4,
@@ -161,6 +172,7 @@
     {
         label: "纳税人识别号",
         prop: "identificationnumber",
+        labelWidth: 160,
         width: 140,
         // addDisplay: true,
         // editDisplay: true,
@@ -203,6 +215,7 @@
     {
         label: "注册地址",
         prop: "address",
+        labelWidth: 160,
         // search: true,
         hide: true,
     },
@@ -210,6 +223,7 @@
         label: "经营范围",
         prop: "business",
         // search: true,
+        labelWidth: 160,
         hide: true,
         // width: 110,
         overHidden: true
@@ -217,6 +231,7 @@
     {
         label: "所属地区",
         prop: "region",
+        labelWidth: 160,
         // width: 110,
         // search: true,
         overHidden: true
@@ -225,6 +240,7 @@
         label: "登记机关",
         prop: "registration",
         // search: true,
+        labelWidth: 160,
         // width: 88,
         overHidden: true,
         hide: true,
@@ -233,6 +249,7 @@
     {
         label: "所属行业",
         prop: "industry",
+        labelWidth: 160,
         hide: true,
         // search: true,
         // width: 88,
@@ -280,7 +297,7 @@
     },
     {
         label: "辖区",
-        prop: "departmentid",
+        prop: "jurisdiction",
         // type: "tree",
         // disabled: true,
         type: "tree",
diff --git a/src/views/securityUnit/index.vue b/src/views/securityUnit/index.vue
index 123fc68..1f876e5 100644
--- a/src/views/securityUnit/index.vue
+++ b/src/views/securityUnit/index.vue
@@ -212,12 +212,13 @@
       query: {},
       data: [],
       option: {
+        index: true,
         addBtn: false,
         // card: true,
         tip: false,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 623,
+        height: 693,
         menuWidth: 160,
         align: "center",
         selection: true,
@@ -421,7 +422,7 @@
           }
         }
       }
-      // console.log(d);
+      console.log(d);
       for (var k in d) {
         if (d[k] == "" || d[k] == undefined) {
           console.log(k);
diff --git a/src/views/singleperformance/index.vue b/src/views/singleperformance/index.vue
new file mode 100644
index 0000000..792827c
--- /dev/null
+++ b/src/views/singleperformance/index.vue
@@ -0,0 +1,398 @@
+/*
+ * @Author: Morpheus
+ * @Date: 2021-07-05 16:31:54
+ * @Last Modified by: Morpheus
+ * @Last Modified time: 2021-07-18 21:02:10
+ * menu-name 成绩管理
+ */
+<template>
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <avue-crud v-model="obj"
+                               class="company-box"
+                               :option="questionBankOption"
+                               :search.sync="questionBankSearch"
+                               :table-loading="questionBankLoading"
+                               :data="questionBankData"
+                               ref="questionBankCrud"
+                               :page.sync="questionBankPage"
+                               @on-load="questionBankOnLoad"
+                               @selection-change="questionBankSelectionChange"
+                               @search-change="questionBankSearchChange"
+                               @search-reset="questionBankSearchReset"
+                               @current-change="questionBankCurrentChange"
+                               @size-change="questionBankSizeChange"
+                               @row-update="questionBankRowUpdate">
+
+                        <template slot-scope="{ row }"
+                                  slot="learnGrade">
+                            {{ row.learnGrade == -1 ? "暂未录入" : row.learnGrade }}
+                        </template>
+
+                        <!-- 自定义按钮 -->
+                        <!-- <template slot="menuLeft">
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">新增
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">删除
+                            </el-button>
+                            <el-button type="danger"
+                                       size="mini"
+                                       icon="el-icon-delete"
+                                       plain
+                                       @click="handleDelete">导出
+                            </el-button>
+                        </template> -->
+
+                    </avue-crud>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+</template>
+
+<script>
+import {
+    getList,
+    update
+} from "@/api/examapi/performance";
+
+
+
+export default {
+
+
+    data () {
+
+        var validatePass = (rule, value, callback) => {
+            console.log(value)
+            if (value == undefined || value == '') {
+                callback(new Error('请输入实操成绩'));
+                return;
+            } else if (value !== '' && isNaN(value) == true) {
+                callback(new Error('请输入数字'));
+            } else if (value <= 0) {
+                callback(new Error('分数设置请大于0'));
+            } else if (value > 100) {
+                callback(new Error('分数设置请小于100'));
+            } else {
+                callback();
+            }
+        };
+
+        return {
+            obj: {
+                name: '张三',
+            },
+            questionBankOption: {
+                // 操作栏多余按钮去除
+                delBtn: false,
+                editBtn: true,
+                addBtn: false,
+                selection: false,
+                // 导出按钮
+                excelBtn: true,
+                excelBtnText: '成绩导出',
+                viewBtn: true,
+                title: '成绩',
+
+                align: 'center',
+                height: 'auto',
+                calcHeight: 80,
+                tip: false,
+                searchShow: true,
+                searchMenuSpan: 4,
+                index: true,
+                indexLabel: '序号',
+                //dialogType: 'drawer',
+                dialogClickModal: false,
+                // 操作栏宽度
+                menu: false,
+                menuWidth: 136,
+                labelWidth: 120,
+
+                column: [
+                    {
+                        label: "试卷名称",
+                        prop: "examName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入试卷名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "保安姓名",
+                        prop: "securityName",
+                        search: true,
+                        searchSpan: 4,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入保安姓名",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "所属公司",
+                        prop: "company",
+                        search: true,
+                        searchSpan: 4,
+                        dicUrl: '/api/blade-system/dept/tree',
+                        props: {
+                            label: "title",
+                            value: "id",
+                        },
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入所属公司",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "考试时间",
+                        prop: "examTime",
+                        type: "datetime",
+                        // span: 24,
+                        format: 'yyyy-MM-dd HH:mm:ss',
+                        valueFormat: 'yyyy-MM-dd HH:mm:ss',
+                        width: 250,
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                    },
+                    {
+                        label: "理论成绩",
+                        prop: "theoryGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+
+                    },
+                    {
+                        label: "实操成绩",
+                        prop: "learnGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: false,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{ validator: validatePass, required: true, trigger: 'blur' }],
+                    },
+                    {
+                        label: "总成绩",
+                        prop: "allGrade",
+                        slot: true,
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入考试名称",
+                            trigger: "blur"
+                        }]
+                    },
+                    {
+                        label: "是否合格",
+                        prop: "qualified",
+                        type: 'select',
+                        slot: true,
+                        search: true,
+                        searchSpan: 4,
+                        dicData: [{
+                            label: '合格',
+                            value: 0
+                        }, {
+                            label: '不合格',
+                            value: 1,
+                        }, {
+                            label: '暂未录实操成绩',
+                            value: 2,
+                        }],
+                        // 表单新增时是否禁止
+                        addDisabled: false,
+                        // 表单新增时是否可见
+                        addDisplay: true,
+                        // 表单新增时是否为查看模式
+                        addDetail: false,
+                        // 表单编辑时是否禁止
+                        editDisabled: true,
+                        // 表单编辑时是否可见
+                        editDisplay: true,
+                        // 表单编辑时是否为查看模式
+                        editDetail: false,
+                        rules: [{
+                            required: true,
+                            message: "请输入考试名称",
+                            trigger: "blur"
+                        }]
+                    },
+                ]
+            },
+            questionBankSearch: {},
+            questionBankLoading: true,
+            questionBankData: [
+            ],
+            questionBankPage: {
+                pageSize: 10,
+                currentPage: 1,
+                total: 16
+            },
+            questionBankQuery: {},
+            questionBankSelectionList: [],
+        }
+    },
+    created () {
+
+
+    },
+    mounted () {
+
+
+    },
+    methods: {
+        questionBankOnLoad (page, params = {}) {
+            this.questionBankLoading = false;
+            getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
+                const data = res.data.data;
+                this.questionBankPage.total = data.total;
+                this.questionBankData = data.records;
+                this.questionBankLoading = false;
+                this.questionBankSelectionClear();
+            });
+        },
+        questionBankSelectionClear () {
+            this.questionBankSelectionList = [];
+            this.$refs.questionBankCrud.toggleSelection();
+        },
+        questionBankSelectionChange (list) {
+            this.questionBankSelectionList = list;
+        },
+        questionBankSearchChange (params, done) {
+            this.questionBankQuery = params;
+            this.questionBankPage.currentPage = 1;
+            this.questionBankOnLoad(this.questionBankPage, params);
+            done();
+        },
+        questionBankSearchReset () {
+            this.questionBankQuery = {};
+            this.questionBankOnLoad(this.questionBankPage);
+        },
+        questionBankCurrentChange (currentPage) {
+            this.questionBankPage.currentPage = currentPage;
+        },
+        questionBankSizeChange (pageSize) {
+            this.questionBankPage.pageSize = pageSize;
+        },
+
+        questionBankRowUpdate (row, index, done, loading) {
+
+            update({ theoryGrade: row.theoryGrade, learnGrade: row.learnGrade, id: row.id }).then(() => {
+                this.questionBankOnLoad(this.questionBankPage);
+                this.$message({
+                    type: "success",
+                    message: "操作成功!"
+                });
+                done();
+            }, error => {
+                window.console.log(error);
+                loading();
+            });
+        },
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/src/views/startexam/index.vue b/src/views/startexam/index.vue
new file mode 100644
index 0000000..4f446a8
--- /dev/null
+++ b/src/views/startexam/index.vue
@@ -0,0 +1,663 @@
+<template>
+
+    <el-row class="morpheus-box">
+        <el-col :span="24">
+            <el-card>
+
+                <div class="exam-card-body">
+
+                    <div class="subject-box">
+                        <el-row :gutter="30">
+                            <el-col :span="5">
+                                <div class="tool-bar">
+                                    <div class="time-remain">
+                                        剩余时间:
+                                        <div class="time">
+                                            <count-down v-on:start_callback="countDownS_cb(1)"
+                                                        v-on:end_callback="countDownE_cb(1)"
+                                                        :current-time="currentTime"
+                                                        :start-time="startTime"
+                                                        :end-time="endTime"
+                                                        :tip-text="'距离考试开始'"
+                                                        :tip-text-end="'距离考试结束'"
+                                                        :end-text="'考试结束'"
+                                                        :hourTxt="':'"
+                                                        :minutesTxt="':'"
+                                                        :secondsTxt="''">
+                                            </count-down>
+                                        </div>
+                                    </div>
+                                    <div class="current-progress">
+                                        当前进度: {{subjectIndex}}/{{subjectIds.length}}
+                                    </div>
+                                    <div class="answer-card">
+                                        <el-button type="text"
+                                                   icon="el-icon-date"
+                                                   @click="answerCard">答题卡</el-button>
+                                    </div>
+                                    <el-button type="success"
+                                               icon="el-icon-date"
+                                               @click="submitExam"
+                                               v-bind:disabled="disableSubmit">提交</el-button>
+                                </div>
+                            </el-col>
+                            <el-col :span="18">
+                                <div class="subject-box-card">
+                                    <div class="subject-exam-title">{{exam.examinationName}}(共{{subjectIds.length}}题,合计{{exam.totalScore}}分)</div>
+                                    <!-- 题目内容 -->
+                                    <choices ref="choices"
+                                             v-show="this.query.type === 0" />
+
+                                    <multiple-choices ref="multipleChoices"
+                                                      v-show="this.query.type === 1" />
+
+                                    <judgement ref="judgement"
+                                               v-show="this.query.type === 2" />
+
+                                    <practical-operation ref="practicalOperation"
+                                                         v-show="this.query.type === 3" />
+
+                                    <short-answer ref="shortAnswer"
+                                                  v-show="this.query.type === 4" />
+
+                                    <div class="subject-buttons"
+                                         v-if="query.subjectId !== ''">
+
+                                        <el-button plain
+                                                   @click="last"
+                                                   :loading="loadingLast">上一题</el-button>
+                                        <el-button plain
+                                                   @click="next"
+                                                   :loading="loadingNext">下一题</el-button>
+                                        <el-button type="success"
+                                                   @click="submitExam"
+                                                   v-bind:disabled="disableSubmit">提交</el-button>
+
+                                    </div>
+                                </div>
+                            </el-col>
+                        </el-row>
+                        <el-dialog title="答题卡"
+                                   :visible.sync="dialogVisible"
+                                   width="50%"
+                                   top="10vh"
+                                   :modal='false'
+                                   center>
+                            <div class="answer-card-title">{{exam.examinationName}}(共{{subjectIds.length}}题,合计{{exam.totalScore}}分)</div>
+                            <div class="answer-card-split"></div>
+                            <el-row class="answer-card-content">
+                                <el-button :class="{ 'answered': subjectIds[index].answered }"
+                                           circle
+                                           v-for="(value, index) in subjectIds"
+                                           :key="index"
+                                           @click="toSubject(value.everyID, value.type, index)">&nbsp;{{index + 1}}&nbsp;</el-button>
+                            </el-row>
+                        </el-dialog>
+                    </div>
+
+                </div>
+
+            </el-card>
+        </el-col>
+    </el-row>
+
+</template>
+<script>
+import { mapState } from 'vuex'
+import CountDown from 'vue2-countdown'
+import { saveAndNext } from '@/api/exam/answer'
+import { getSubjectIds } from '@/api/exam/exam'
+import { getCurrentTime } from '@/api/exam/examRecord'
+import { getSubjectAnswer } from '@/api/exam/subject'
+
+import moment from 'moment'
+import { messageSuccess, messageFail, messageWarn, isNotEmpty } from '@/util/util'
+import Tinymce from '@/components/Tinymce'
+import Choices from '@/components/Subjects/Choices'
+
+import MultipleChoices from '@/components/Subjects/MultipleChoices'
+import PracticalOperation from '@/components/Subjects/PracticalOperation'
+
+
+
+
+// import ShortAnswer from '@/components/Subjects/ShortAnswer'
+import Judgement from '@/components/Subjects/Judgement'
+
+import { nextSubjectType } from '@/const/constant'
+
+export default {
+    components: {
+        CountDown,
+        Tinymce,
+        Choices,
+        MultipleChoices,
+        PracticalOperation,
+        Judgement,
+        // ShortAnswer,
+    },
+    data () {
+        return {
+            loadingLast: false,
+            loadingNext: false,
+
+            currentTime: 0,
+            startTime: 0,
+            endTime: 0,
+            disableSubmit: true,
+            subjectIndex: 1,
+            query: {
+                examinationId: undefined,
+                examRecordId: undefined,
+                subjectId: undefined,
+                userId: undefined,
+                type: 0
+            },
+            subject: {},
+            answer: '',
+            dialogVisible: false,
+            subjectIds: [],
+            subjectStartTime: undefined,
+            exam: {
+                id: '590969316204220416',
+                creator: 'admin',
+                createDate: 1560939664000,
+                modifier: 'preview',
+                modifyDate: 1609835214000,
+
+                delFlag: 0,
+
+                examinationName: '',
+
+                startTime: null,
+                endTime: null,
+
+                totalScore: 50,
+
+                status: 0,
+
+
+                remark: '全国计算机统考练习题10道',
+
+                newRecord: false
+            },
+            firstFlag: true
+        }
+    },
+    computed: {
+        ...mapState({
+            userInfo: state => state.user.userInfo
+        })
+    },
+    created () {
+
+        const examInfo = this.$route.params.id
+
+        if (isNotEmpty(examInfo)) {
+            // 试卷ID
+            this.query.examinationId = this.$route.params.id
+
+            // 考场ID
+            this.query.examRecordId = this.userInfo.user_id
+
+            this.query.userId = this.userInfo.user_id
+
+            this.exam.id = this.userInfo.user_id + '' + this.$route.params.id
+
+            this.exam.examinationName = this.$route.query.examName
+            this.exam.startTime = this.$route.query.startTime
+            this.exam.endTime = this.$route.query.endTime
+            this.exam.totalScore = this.$route.query.totalScore
+            this.exam.status = this.$route.query.examStatus
+            this.exam.remark = this.$route.query.remark
+
+            this.validateExamTime()
+        }
+    },
+    methods: {
+        countDownS_cb: function () {
+            messageSuccess(this, '考试开始')
+        },
+        validateExamTime () {
+            getCurrentTime().then(response => {
+                const currentTime = moment(response.data.data)
+                if (currentTime.isAfter(this.exam.endTime)) {
+                    messageWarn(this, '考试已结束')
+                } else if (currentTime.isBefore(this.exam.startTime)) {
+                    messageWarn(this, '考试未开始')
+                } else {
+                    this.startExam()
+                    const current = currentTime.valueOf()
+                    this.currentTime = current
+                    this.startTime = current
+                    this.subjectStartTime = current
+                    this.endTime = moment(this.exam.endTime).valueOf()
+                    this.disableSubmit = false
+                }
+            }).catch(() => {
+                messageFail(this, '开始考试失败!15')
+            })
+        },
+        startExam () {
+            // 获取题目ID列表
+            getSubjectIds({ id: this.query.examinationId }).then(subjectResponse => {
+                const subjectData = subjectResponse.data.data.examExaminationSubjects
+                if (subjectData.length > 0) {
+                    for (let i = 0; i < subjectData.length; i++) {
+                        const { examSubjectChoices } = subjectData[i]
+                        this.subjectIds.push({
+                            subjectId: subjectResponse.data.data.id,
+                            everyID: examSubjectChoices.id,
+                            type: examSubjectChoices.choicesType,
+                            index: i + 1,
+                            answered: false,
+                            answer: examSubjectChoices.answer,
+                            score: examSubjectChoices.score
+                        })
+                    }
+
+                    this.query.type = parseInt(this.subjectIds[0].type)
+
+                    // 准考证号
+                    this.query.subjectId = this.subjectIds[0].everyID
+
+                    this.updateSubjectIndex()
+                    // 获取当前题目信息
+                    getSubjectAnswer({
+                        id: this.subjectIds[0].everyID,
+                    }).then(response => {
+                        if (isNotEmpty(response.data.data)) {
+                            this.setSubjectInfo(response.data.data)
+                        }
+                    }).catch(() => {
+                        messageFail(this, '获取题目失败!')
+                    })
+                }
+            }).catch(() => {
+                messageFail(this, '开始考试失败!4646549888*8*')
+            })
+        },
+        countDownE_cb: function () {
+            messageWarn(this, '考试结束')
+            this.disableSubmit = true
+        },
+        last () {
+
+            for (let i = 0; i < this.subjectIds.length; i++) {
+
+                if (this.subjectIds[i].everyID == this.query.subjectId) {
+
+                    this.subjectIds[i].answer = this.getAnswer()
+
+                    this.markAnswered(this.subjectIds[i].answer, i)
+
+                    if (i === 0) {
+                        messageSuccess(this, '已经是第一题了')
+                        break
+                    }
+
+                    let { everyID, type, index } = this.subjectIds[--i]
+
+                    this.subjectIndex = index
+
+                    this.saveCurrentSubjectAndGetNextSubject(nextSubjectType.last, everyID, type)
+
+                    break
+
+                }
+
+            }
+
+        },
+        next () {
+
+            for (let i = 0; i < this.subjectIds.length; i++) {
+
+                if (this.subjectIds[i].everyID == this.query.subjectId) {
+
+                    this.subjectIds[i].answer = this.getAnswer()
+
+                    this.markAnswered(this.subjectIds[i].answer, i)
+
+                    if (i === this.subjectIds.length - 1) {
+                        messageSuccess(this, '已经是最后一题了')
+                        break
+                    }
+
+                    let { everyID, index } = this.subjectIds[++i]
+
+                    this.subjectIndex = index
+
+                    this.saveCurrentSubjectAndGetNextSubject(nextSubjectType.next, everyID)
+
+                    break
+
+                }
+
+            }
+
+        },
+        // 保存当前题目,同时根据序号加载下一题
+        saveCurrentSubjectAndGetNextSubject (nextType, nextSubjectId) {
+
+
+            this.startLoading(nextType)
+
+            getSubjectAnswer({ id: nextSubjectId }).then(response => {
+
+                if (response.data.data !== null) {
+
+                    // 保存成功后更新答题卡状态
+                    const subject = response.data.data
+                    const { id, choicesType } = subject
+
+                    this.query.subjectId = id
+
+                    this.query.type = choicesType
+
+                    for (let i = 0; i < this.subjectIds.length; i++) {
+
+                        if (this.subjectIds[i].everyID == nextSubjectId) {
+
+                            subject.answer = this.subjectIds[i].answer
+
+                            break
+
+                        }
+
+                    }
+
+
+
+                    this.setSubjectInfo(subject)
+
+                    // store.dispatch('SetSubjectInfo', subject).then(() => { })
+
+                }
+                // 更新时间
+                getCurrentTime().then(response => {
+                    this.subjectStartTime = moment(response.data.data)
+                })
+                this.endLoading(nextType)
+            }).catch((error) => {
+                console.log(error)
+                messageFail(this, '获取题目失败')
+                this.endLoading(nextType)
+            })
+        },
+        markAnswered (answer, index) {
+            if (answer && answer !== null) {
+                this.subjectIds[index].answered = true
+            }
+        },
+        // 答题卡
+        answerCard () {
+            this.dialogVisible = true
+        },
+        // 跳转题目
+        toSubject (everyID, type, index) {
+
+            var ind = this.subjectIndex;
+
+            if (this.firstFlag == false) {
+                ind = this.subjectIndex;
+            } else {
+                ind = this.subjectIndex - 1;
+            }
+
+
+            this.subjectIds[ind].answer = this.getAnswer()
+
+            this.markAnswered(this.subjectIds[ind].answer, ind)
+
+            this.subjectIndex = index + 1
+            this.firstFlag = true;
+            // 保存当前题目,同时加载下一题
+            this.saveCurrentSubjectAndGetNextSubject(nextSubjectType.next, everyID, type)
+
+            this.dialogVisible = false
+        },
+        // 提交
+        submitExam () {
+
+            var ind = this.subjectIndex;
+
+            if (this.firstFlag == false) {
+                ind = this.subjectIndex;
+            } else {
+                ind = this.subjectIndex - 1;
+            }
+
+
+            this.subjectIds[ind].answer = this.getAnswer()
+
+            this.markAnswered(this.subjectIds[ind].answer, ind)
+
+            this.$confirm('确定要提交吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                this.disableSubmit = true
+                this.doSubmitExam()
+            }).catch(() => {
+            })
+        },
+        doSubmitExam () {
+
+            var obj = {
+                examName: this.$route.query.examName,
+                securityName: this.userInfo.user_name,
+                securityId: this.userInfo.user_id,
+                allScore: this.$route.query.totalScore,
+                company: this.userInfo.dept_id,
+                examTime: this.$route.query.startTime,
+                papersId: this.$route.query.id,
+                examEndTime: this.$route.query.endTime,
+                examResultVOS: null
+
+            }
+
+            var arr = []
+
+
+            this.subjectIds.forEach((item) => {
+
+
+                if (item.type == 3) {
+
+                    var str = ''
+
+                    if (item.answer.length > 0) {
+                        item.answer.forEach(it => {
+
+                            if (it.value != '') {
+                                str += it.value + ','
+                            }
+
+                        })
+
+                        var a = str.substr(0, str.length - 1);
+
+
+                        arr.push(
+                            {
+                                "subjectChoicesId": item.everyID,
+                                "value": a,
+                                "grade": item.score
+                            }
+
+                        )
+                    }
+                } else {
+                    arr.push(
+                        {
+                            "subjectChoicesId": item.everyID,
+                            "value": item.answer,
+                            "grade": item.score
+                        }
+
+                    )
+                }
+
+            })
+
+            obj.examResultVOS = arr
+
+            saveAndNext(obj).then(response => {
+                messageSuccess(this, '提交成功')
+                if (response) {
+                    this.$store.commit("DEL_TAG", this.$store.state.tags.tag);
+                    this.$router.push({
+                        path: `/singleperformance/index`,
+                    });
+                }
+
+            }).catch(() => {
+                this.disableSubmit = false
+                messageFail(this, '提交题目失败')
+            })
+        },
+        // 选中选项
+        toggleOption (answer) {
+            this.answer = answer
+        },
+        // 根据题目类型返回填写的答案
+        getAnswer () {
+            const ref = this.getSubjectRef()
+            if (isNotEmpty(ref)) {
+                const answer = ref.getAnswer()
+                this.answer = answer
+                return answer
+                // {
+                //     id: answerId,
+                //     userId: this.userInfo.id,
+                //     examinationId: this.query.examinationId,
+                //     examRecordId: this.query.examRecordId,
+                //     subjectId: this.query.subjectId,
+                //     answer: answer,
+                //     type: this.query.type,
+                //     startTime: this.subjectStartTime
+                // }
+            }
+            return {}
+        },
+        // 获取题目索引
+        getSubjectIndex (targetId) {
+            for (let subject of this.subjectIds) {
+                let { subjectId, index } = subject
+                if (subjectId === targetId) {
+                    return index
+                }
+            }
+            return 1
+        },
+        // 更新题目索引
+        updateSubjectIndex () {
+            this.subjectIndex = this.getSubjectIndex(this.query.subjectId)
+        },
+        startLoading (nextType) {
+            if (nextType === nextSubjectType.next) {
+                this.loadingNext = true
+            } else if (nextType === nextSubjectType.last) {
+                this.loadingLast = true
+            } else {
+                this.loadingNext = true
+            }
+        },
+        endLoading (nextType) {
+            if (nextType === nextSubjectType.next) {
+                this.loadingNext = false
+            } else if (nextType === nextSubjectType.last) {
+                this.loadingLast = false
+            } else {
+                this.loadingNext = false
+            }
+        },
+        getSubjectRef () {
+            let ref
+
+            switch (this.query.type) {
+                case 0:
+                    ref = this.$refs.choices
+                    break
+                case 1:
+                    ref = this.$refs.multipleChoices
+
+                    break
+                case 2:
+                    ref = this.$refs.judgement
+                    break
+                case 3:
+                    ref = this.$refs.practicalOperation
+                    break
+                case 4:
+                    ref = this.$refs.shortAnswer
+                    break
+            }
+            return ref
+        },
+        setSubjectInfo (subject) {
+
+            const ref = this.getSubjectRef()
+
+            if (isNotEmpty(ref)) {
+                try {
+                    ref.setSubjectInfo(subject, this.subjectIds.length, this.subjectIndex)
+                } catch (error) {
+                    console.error(error)
+                }
+            }
+        }
+    }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style lang="scss" rel="stylesheet/scss" scoped>
+.subject-box {
+    margin-top: 50px;
+    margin-left: 20px;
+}
+.subject-box-card {
+    width: 80%;
+    margin-bottom: 30px;
+    min-height: 400px;
+}
+.subject-buttons {
+    text-align: right;
+}
+.tool-bar {
+    margin-left: 20px;
+}
+.time-remain .time {
+    display: inline-block;
+    font-size: 18px;
+    line-height: 22px;
+    color: #ff0000;
+    font-weight: 400;
+}
+
+/* 答题卡 */
+.answer-card-title {
+    font-size: 13px;
+    color: #3a3e51;
+    line-height: 17px;
+    padding: 10px 0;
+}
+.answer-card-split {
+    width: 100%;
+    border-bottom: 1px solid #e6e6e6;
+}
+.answer-card-content {
+    padding-bottom: 10px;
+    font-size: 0;
+    margin-right: -15px;
+    > button {
+        margin-top: 5px;
+    }
+}
+.answered {
+    background-color: greenyellow;
+}
+</style>
diff --git a/src/views/system/client.vue b/src/views/system/client.vue
index 2a1892b..cc0bcca 100644
--- a/src/views/system/client.vue
+++ b/src/views/system/client.vue
@@ -1,30 +1,34 @@
 <template>
-  <basic-container>
-    <avue-crud :option="option"
-               :table-loading="loading"
-               :data="data"
-               :page.sync="page"
-               @row-del="rowDel"
-               v-model="form"
-               ref="crud"
-               :permission="permissionList"
-               @row-update="rowUpdate"
-               @row-save="rowSave"
-               :before-open="beforeOpen"
-               @search-change="searchChange"
-               @search-reset="searchReset"
-               @selection-change="selectionChange"
-               @current-change="currentChange"
-               @size-change="sizeChange"
-               @refresh-change="refreshChange"
-               @on-load="onLoad">
+  <basic-container class="hasButOne">
+    <avue-crud
+      :option="option"
+      :table-loading="loading"
+      :data="data"
+      :page.sync="page"
+      @row-del="rowDel"
+      v-model="form"
+      ref="crud"
+      :permission="permissionList"
+      @row-update="rowUpdate"
+      @row-save="rowSave"
+      :before-open="beforeOpen"
+      @search-change="searchChange"
+      @search-reset="searchReset"
+      @selection-change="selectionChange"
+      @current-change="currentChange"
+      @size-change="sizeChange"
+      @refresh-change="refreshChange"
+      @on-load="onLoad"
+    >
       <template slot="menuLeft">
-        <el-button type="danger"
-                   size="small"
-                   icon="el-icon-delete"
-                   plain
-                   v-if="permission.client_delete"
-                   @click="handleDelete">删 除
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          plain
+          v-if="permission.client_delete"
+          @click="handleDelete"
+          >删 除
         </el-button>
       </template>
     </avue-crud>
@@ -32,301 +36,333 @@
 </template>
 
 <script>
-  import {getList, getDetail, add, update, remove} from "@/api/system/client";
-  import {mapGetters} from "vuex";
+import { getList, getDetail, add, update, remove } from "@/api/system/client";
+import { mapGetters } from "vuex";
 
-  export default {
-    data() {
-      return {
-        form: {},
-        query: {},
-        loading: true,
-        page: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0
-        },
-        selectionList: [],
-        option: {
-          height: 'auto',
-          calcHeight: 30,
-          tip: false,
-          searchShow: true,
-          searchMenuSpan: 6,
-          border: true,
-          index: true,
-          viewBtn: true,
-          selection: true,
-          dialogClickModal: false,
-          column: [
-            {
-              label: "应用id",
-              prop: "clientId",
-              search: true,
-              rules: [{
+export default {
+  data() {
+    return {
+      form: {},
+      query: {},
+      loading: true,
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0,
+      },
+      selectionList: [],
+      option: {
+        height: "auto",
+        calcHeight: 30,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 6,
+        border: true,
+        index: true,
+        viewBtn: true,
+        selection: true,
+        dialogClickModal: false,
+        column: [
+          {
+            label: "应用id",
+            prop: "clientId",
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入客户端id",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "应用密钥",
-              prop: "clientSecret",
-              search: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "应用密钥",
+            prop: "clientSecret",
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入客户端密钥",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "授权类型",
-              prop: "authorizedGrantTypes",
-              type: "checkbox",
-              value: "refresh_token,password,authorization_code",
-              dicData: [
-                {
-                  label: "refresh_token",
-                  value: "refresh_token"
-                },
-                {
-                  label: "password",
-                  value: "password"
-                },
-                {
-                  label: "authorization_code",
-                  value: "authorization_code"
-                },
-                {
-                  label: "captcha",
-                  value: "captcha"
-                },
-                {
-                  label: "social",
-                  value: "social"
-                }
-              ],
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "授权类型",
+            prop: "authorizedGrantTypes",
+            type: "checkbox",
+            value: "refresh_token,password,authorization_code",
+            dicData: [
+              {
+                label: "refresh_token",
+                value: "refresh_token",
+              },
+              {
+                label: "password",
+                value: "password",
+              },
+              {
+                label: "authorization_code",
+                value: "authorization_code",
+              },
+              {
+                label: "captcha",
+                value: "captcha",
+              },
+              {
+                label: "social",
+                value: "social",
+              },
+            ],
+            rules: [
+              {
                 required: true,
                 message: "请输入授权类型",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "授权范围",
-              prop: "scope",
-              value: "all",
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "授权范围",
+            prop: "scope",
+            value: "all",
+            rules: [
+              {
                 required: true,
                 message: "请输入授权范围",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "令牌秒数",
-              prop: "accessTokenValidity",
-              type: "number",
-              value: 3600,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "令牌秒数",
+            prop: "accessTokenValidity",
+            type: "number",
+            value: 3600,
+            rules: [
+              {
                 required: true,
                 message: "请输入令牌过期秒数",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "刷新秒数",
-              prop: "refreshTokenValidity",
-              type: "number",
-              value: 604800,
-              hide: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "刷新秒数",
+            prop: "refreshTokenValidity",
+            type: "number",
+            value: 604800,
+            hide: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入刷新令牌过期秒数",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "回调地址",
-              prop: "webServerRedirectUri",
-              hide: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "回调地址",
+            prop: "webServerRedirectUri",
+            hide: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入回调地址",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "资源集合",
-              prop: "resourceIds",
-              hide: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "资源集合",
+            prop: "resourceIds",
+            hide: true,
+            rules: [
+              {
                 message: "请输入资源集合",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "权限",
-              prop: "authorities",
-              hide: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "权限",
+            prop: "authorities",
+            hide: true,
+            rules: [
+              {
                 message: "请输入权限",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "自动授权",
-              prop: "autoapprove",
-              hide: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "自动授权",
+            prop: "autoapprove",
+            hide: true,
+            rules: [
+              {
                 message: "请输入自动授权",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "附加说明",
-              hide: true,
-              prop: "additionalInformation",
-              span: 24,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "附加说明",
+            hide: true,
+            prop: "additionalInformation",
+            span: 24,
+            rules: [
+              {
                 message: "请输入附加说明",
-                trigger: "blur"
-              }]
-            },
-          ]
-        },
-        data: []
+                trigger: "blur",
+              },
+            ],
+          },
+        ],
+      },
+      data: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission.client_add),
+        viewBtn: this.vaildData(this.permission.client_view),
+        delBtn: this.vaildData(this.permission.client_delete),
+        editBtn: this.vaildData(this.permission.client_edit),
       };
     },
-    computed: {
-      ...mapGetters(["permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.client_add),
-          viewBtn: this.vaildData(this.permission.client_view),
-          delBtn: this.vaildData(this.permission.client_delete),
-          editBtn: this.vaildData(this.permission.client_edit)
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
-      }
+    ids() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
     },
-    methods: {
-      rowSave(row, done, loading) {
-        add(row).then(() => {
+  },
+  methods: {
+    rowSave(row, done, loading) {
+      add(row).then(
+        () => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowUpdate(row, index, done, loading) {
-        update(row).then(() => {
+        }
+      );
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(
+        () => {
           this.onLoad(this.page);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
+        }
+      );
+    },
+    rowDel(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
         });
-      },
-      rowDel(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
+    },
+    searchReset() {
+      this.query = {};
+      this.onLoad(this.page);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
         })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
           });
-      },
-      searchReset() {
-        this.query = {};
-        this.onLoad(this.page);
-      },
-      searchChange(params, done) {
-        this.query = params;
-        this.page.currentPage = 1;
-        this.onLoad(this.page, params);
-        done();
-      },
-      selectionChange(list) {
-        this.selectionList = list;
-      },
-      selectionClear() {
-        this.selectionList = [];
-        this.$refs.crud.toggleSelection();
-      },
-      handleDelete() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
-        }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crud.toggleSelection();
-          });
-      },
-      beforeOpen(done, type) {
-        if (["edit", "view"].includes(type)) {
-          getDetail(this.form.id).then(res => {
-            this.form = res.data.data;
-          });
-        }
-        done();
-      },
-      currentChange(currentPage) {
-        this.page.currentPage = currentPage;
-      },
-      sizeChange(pageSize) {
-        this.page.pageSize = pageSize;
-      },
-      refreshChange() {
-        this.onLoad(this.page, this.query);
-      },
-      onLoad(page, params = {}) {
-        this.loading = true;
-        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
-          const data = res.data.data;
-          this.page.total = data.total;
-          this.data = data.records;
-          this.loading = false;
-          this.selectionClear();
+          this.$refs.crud.toggleSelection();
+        });
+    },
+    beforeOpen(done, type) {
+      if (["edit", "view"].includes(type)) {
+        getDetail(this.form.id).then((res) => {
+          this.form = res.data.data;
         });
       }
-    }
-  };
+      done();
+    },
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoad(this.page, this.query);
+    },
+    onLoad(page, params = {}) {
+      this.loading = true;
+      getList(
+        page.currentPage,
+        page.pageSize,
+        Object.assign(params, this.query)
+      ).then((res) => {
+        const data = res.data.data;
+        this.page.total = data.total;
+        this.data = data.records;
+        this.loading = false;
+        this.selectionClear();
+      });
+    },
+  },
+};
 </script>
 
 <style>
diff --git a/src/views/system/dept.vue b/src/views/system/dept.vue
index e9d1e9d..d524f13 100644
--- a/src/views/system/dept.vue
+++ b/src/views/system/dept.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="hasButTwo">
     <avue-crud
       :option="option"
       :table-loading="loading"
diff --git a/src/views/system/dict.vue b/src/views/system/dict.vue
index 1355028..9265d5b 100644
--- a/src/views/system/dict.vue
+++ b/src/views/system/dict.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="hasButTwo">
     <avue-crud
       :option="optionParent"
       :table-loading="loading"
@@ -29,7 +29,7 @@
           v-if="permission.dict_delete"
           plain
           @click="handleDelete"
-        >删 除
+          >删 除
         </el-button>
       </template>
       <template slot-scope="scope" slot="menu">
@@ -39,20 +39,24 @@
           size="small"
           @click.stop="handleRowClick(scope.row)"
           v-if="userInfo.role_name.includes('admin')"
-        >字典配置
+          >字典配置
         </el-button>
       </template>
-      <template slot-scope="{row}" slot="code">
-        <el-tag @click="handleRowClick(row)" style="cursor:pointer">{{ row.code }}</el-tag>
+      <template slot-scope="{ row }" slot="code">
+        <el-tag @click="handleRowClick(row)" style="cursor: pointer">{{
+          row.code
+        }}</el-tag>
       </template>
-      <template slot-scope="{row}" slot="isSealed">
-        <el-tag>{{ row.isSealed === 0 ? '否' : '是' }}</el-tag>
+      <template slot-scope="{ row }" slot="isSealed">
+        <el-tag>{{ row.isSealed === 0 ? "否" : "是" }}</el-tag>
       </template>
     </avue-crud>
-    <el-dialog :title="`[${dictValue}]字典配置`"
-               append-to-body
-               :visible.sync="box"
-               width="1000px">
+    <el-dialog
+      :title="`[${dictValue}]字典配置`"
+      append-to-body
+      :visible.sync="box"
+      width="1000px"
+    >
       <avue-crud
         :option="optionChild"
         :table-loading="loadingChild"
@@ -81,7 +85,7 @@
             v-if="permission.dict_delete"
             plain
             @click="handleDelete"
-          >删 除
+            >删 除
           </el-button>
         </template>
         <template slot-scope="scope" slot="menu">
@@ -89,13 +93,13 @@
             type="text"
             icon="el-icon-circle-plus-outline"
             size="small"
-            @click.stop="handleAdd(scope.row,scope.index)"
+            @click.stop="handleAdd(scope.row, scope.index)"
             v-if="userInfo.role_name.includes('admin')"
-          >新增子项
+            >新增子项
           </el-button>
         </template>
-        <template slot-scope="{row}" slot="isSealed">
-          <el-tag>{{ row.isSealed === 0 ? '否' : '是' }}</el-tag>
+        <template slot-scope="{ row }" slot="isSealed">
+          <el-tag>{{ row.isSealed === 0 ? "否" : "是" }}</el-tag>
         </template>
       </avue-crud>
     </el-dialog>
@@ -110,15 +114,15 @@
   update,
   add,
   getDict,
-  getDictTree
+  getDictTree,
 } from "@/api/system/dict";
-import {optionParent, optionChild} from "@/option/system/dict";
-import {mapGetters} from "vuex";
+import { optionParent, optionChild } from "@/option/system/dict";
+import { mapGetters } from "vuex";
 
 export default {
   data() {
     return {
-      dictValue: '暂无',
+      dictValue: "暂无",
       parentId: -1,
       formParent: {},
       formChild: {},
@@ -131,13 +135,13 @@
         pageSize: 10,
         pageSizes: [10, 30, 50, 100, 200],
         currentPage: 1,
-        total: 0
+        total: 0,
       },
       pageChild: {
         pageSize: 10,
         pageSizes: [10, 30, 50, 100, 200],
         currentPage: 1,
-        total: 0
+        total: 0,
       },
       dataParent: [],
       dataChild: [],
@@ -157,18 +161,18 @@
     },
     ids() {
       let ids = [];
-      this.selectionList.forEach(ele => {
+      this.selectionList.forEach((ele) => {
         ids.push(ele.id);
       });
       return ids.join(",");
-    }
+    },
   },
   mounted() {
     this.initData();
   },
   methods: {
     initData() {
-      getDictTree().then(res => {
+      getDictTree().then((res) => {
         const column = this.findObject(this.optionChild.column, "parentId");
         column.dicData = res.data.data;
       });
@@ -187,37 +191,43 @@
         ...row,
         dictKey: -1,
       };
-      add(form).then(() => {
-        this.onLoadParent(this.pageParent);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        done();
-      }, error => {
-        window.console.log(error);
-        loading();
-      });
+      add(form).then(
+        () => {
+          this.onLoadParent(this.pageParent);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
     },
     rowUpdate(row, index, done, loading) {
-      update(row).then(() => {
-        this.onLoadParent(this.pageParent);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        this.onLoadChild(this.pageChild);
-        done();
-      }, error => {
-        window.console.log(error);
-        loading();
-      });
+      update(row).then(
+        () => {
+          this.onLoadParent(this.pageParent);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.onLoadChild(this.pageChild);
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
     },
     rowDel(row) {
       this.$confirm("确定将选择数据删除?", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
-        type: "warning"
+        type: "warning",
       })
         .then(() => {
           return remove(row.id);
@@ -226,7 +236,7 @@
           this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
         });
     },
@@ -268,7 +278,7 @@
       this.$confirm("确定将选择数据删除?", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
-        type: "warning"
+        type: "warning",
       })
         .then(() => {
           return remove(this.ids);
@@ -277,14 +287,14 @@
           this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           this.$refs.crud.toggleSelection();
         });
     },
     beforeOpen(done, type) {
       if (["edit", "view"].includes(type)) {
-        getDict(this.formParent.id).then(res => {
+        getDict(this.formParent.id).then((res) => {
           this.formParent = res.data.data;
         });
       }
@@ -300,36 +310,42 @@
       this.onLoadParent(this.pageParent, this.query);
     },
     rowSaveChild(row, done, loading) {
-      add(row).then(() => {
-        this.onLoadChild(this.pageChild);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        done();
-      }, error => {
-        window.console.log(error);
-        loading();
-      });
+      add(row).then(
+        () => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
     },
     rowUpdateChild(row, index, done, loading) {
-      update(row).then(() => {
-        this.onLoadChild(this.pageChild);
-        this.$message({
-          type: "success",
-          message: "操作成功!"
-        });
-        done();
-      }, error => {
-        window.console.log(error);
-        loading();
-      });
+      update(row).then(
+        () => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
     },
     rowDelChild(row) {
       this.$confirm("确定将选择数据删除?", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
-        type: "warning"
+        type: "warning",
       })
         .then(() => {
           return remove(row.id);
@@ -338,7 +354,7 @@
           this.onLoadChild(this.pageChild);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
         });
     },
@@ -367,7 +383,7 @@
       this.$confirm("确定将选择数据删除?", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
-        type: "warning"
+        type: "warning",
       })
         .then(() => {
           return remove(this.ids);
@@ -376,7 +392,7 @@
           this.onLoadChild(this.pageChild);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           this.$refs.crudChild.toggleSelection();
         });
@@ -386,7 +402,7 @@
         this.initData();
       }
       if (["edit", "view"].includes(type)) {
-        getDict(this.formChild.id).then(res => {
+        getDict(this.formChild.id).then((res) => {
           this.formChild = res.data.data;
         });
       }
@@ -394,7 +410,7 @@
     },
     beforeCloseChild(done) {
       this.$refs.crudChild.value.parentId = this.parentId;
-      this.$refs.crudChild.option.column.filter(item => {
+      this.$refs.crudChild.option.column.filter((item) => {
         if (item.prop === "parentId") {
           item.value = this.parentId;
         }
@@ -416,7 +432,7 @@
         page.currentPage,
         page.pageSize,
         Object.assign(params, this.query)
-      ).then(res => {
+      ).then((res) => {
         const data = res.data.data;
         this.pageParent.total = data.total;
         this.dataParent = data.records;
@@ -431,13 +447,13 @@
         page.pageSize,
         this.parentId,
         Object.assign(params, this.query)
-      ).then(res => {
+      ).then((res) => {
         this.dataChild = res.data.data;
         this.loadingChild = false;
         this.selectionClear();
       });
-    }
-  }
+    },
+  },
 };
 </script>
 
diff --git a/src/views/system/dictbiz.vue b/src/views/system/dictbiz.vue
index d7772fe..4623510 100644
--- a/src/views/system/dictbiz.vue
+++ b/src/views/system/dictbiz.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="hasButTwo">
     <avue-crud
       :option="optionParent"
       :table-loading="loading"
@@ -29,7 +29,7 @@
           v-if="permission.dictbiz_delete"
           plain
           @click="handleDelete"
-        >删 除
+          >删 除
         </el-button>
       </template>
       <template slot-scope="scope" slot="menu">
@@ -39,20 +39,24 @@
           size="small"
           @click.stop="handleRowClick(scope.row)"
           v-if="userInfo.role_name.includes('admin')"
-        >字典配置
+          >字典配置
         </el-button>
       </template>
-      <template slot-scope="{row}" slot="code">
-        <el-tag @click="handleRowClick(row)" style="cursor:pointer">{{ row.code }}</el-tag>
+      <template slot-scope="{ row }" slot="code">
+        <el-tag @click="handleRowClick(row)" style="cursor: pointer">{{
+          row.code
+        }}</el-tag>
       </template>
-      <template slot-scope="{row}" slot="isSealed">
-        <el-tag>{{ row.isSealed === 0 ? '否' : '是' }}</el-tag>
+      <template slot-scope="{ row }" slot="isSealed">
+        <el-tag>{{ row.isSealed === 0 ? "否" : "是" }}</el-tag>
       </template>
     </avue-crud>
-    <el-dialog :title="`[${dictValue}]字典配置`"
-               append-to-body
-               :visible.sync="box"
-               width="1000px">
+    <el-dialog
+      :title="`[${dictValue}]字典配置`"
+      append-to-body
+      :visible.sync="box"
+      width="1000px"
+    >
       <avue-crud
         :option="optionChild"
         :table-loading="loadingChild"
@@ -81,7 +85,7 @@
             v-if="permission.dict_delete"
             plain
             @click="handleDelete"
-          >删 除
+            >删 除
           </el-button>
         </template>
         <template slot-scope="scope" slot="menu">
@@ -89,13 +93,13 @@
             type="text"
             icon="el-icon-circle-plus-outline"
             size="small"
-            @click.stop="handleAdd(scope.row,scope.index)"
+            @click.stop="handleAdd(scope.row, scope.index)"
             v-if="userInfo.role_name.includes('admin')"
-          >新增子项
+            >新增子项
           </el-button>
         </template>
-        <template slot-scope="{row}" slot="isSealed">
-          <el-tag>{{ row.isSealed === 0 ? '否' : '是' }}</el-tag>
+        <template slot-scope="{ row }" slot="isSealed">
+          <el-tag>{{ row.isSealed === 0 ? "否" : "是" }}</el-tag>
         </template>
       </avue-crud>
     </el-dialog>
@@ -103,340 +107,352 @@
 </template>
 
 <script>
-  import {
-    getParentList,
-    getChildList,
-    remove,
-    update,
-    add,
-    getDict,
-    getDictTree
-  } from "@/api/system/dictbiz";
-  import {optionParent, optionChild} from "@/option/system/dictbiz";
-  import {mapGetters} from "vuex";
+import {
+  getParentList,
+  getChildList,
+  remove,
+  update,
+  add,
+  getDict,
+  getDictTree,
+} from "@/api/system/dictbiz";
+import { optionParent, optionChild } from "@/option/system/dictbiz";
+import { mapGetters } from "vuex";
 
-  export default {
-    data() {
+export default {
+  data() {
+    return {
+      dictValue: "暂无",
+      parentId: -1,
+      formParent: {},
+      formChild: {},
+      selectionList: [],
+      query: {},
+      box: false,
+      loading: true,
+      loadingChild: true,
+      pageParent: {
+        pageSize: 10,
+        pageSizes: [10, 30, 50, 100, 200],
+        currentPage: 1,
+        total: 0,
+      },
+      pageChild: {
+        pageSize: 10,
+        pageSizes: [10, 30, 50, 100, 200],
+        currentPage: 1,
+        total: 0,
+      },
+      dataParent: [],
+      dataChild: [],
+      optionParent: optionParent,
+      optionChild: optionChild,
+    };
+  },
+  computed: {
+    ...mapGetters(["userInfo", "permission"]),
+    permissionList() {
       return {
-        dictValue: '暂无',
-        parentId: -1,
-        formParent: {},
-        formChild: {},
-        selectionList: [],
-        query: {},
-        box: false,
-        loading: true,
-        loadingChild: true,
-        pageParent: {
-          pageSize: 10,
-          pageSizes: [10, 30, 50, 100, 200],
-          currentPage: 1,
-          total: 0
-        },
-        pageChild: {
-          pageSize: 10,
-          pageSizes: [10, 30, 50, 100, 200],
-          currentPage: 1,
-          total: 0
-        },
-        dataParent: [],
-        dataChild: [],
-        optionParent: optionParent,
-        optionChild: optionChild,
+        addBtn: this.vaildData(this.permission.dictbiz_add, false),
+        delBtn: this.vaildData(this.permission.dictbiz_delete, false),
+        editBtn: this.vaildData(this.permission.dictbiz_edit, false),
+        viewBtn: false,
       };
     },
-    computed: {
-      ...mapGetters(["userInfo", "permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.dictbiz_add, false),
-          delBtn: this.vaildData(this.permission.dictbiz_delete, false),
-          editBtn: this.vaildData(this.permission.dictbiz_edit, false),
-          viewBtn: false,
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
-      }
+    ids() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
     },
-    mounted() {
-      this.initData();
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    initData() {
+      getDictTree().then((res) => {
+        const column = this.findObject(this.optionChild.column, "parentId");
+        column.dicData = res.data.data;
+      });
     },
-    methods: {
-      initData() {
-        getDictTree().then(res => {
-          const column = this.findObject(this.optionChild.column, "parentId");
-          column.dicData = res.data.data;
-        });
-      },
-      handleAdd(row) {
-        this.formChild.dictValue = "";
-        this.formChild.dictKey = "";
-        this.formChild.sort = 0;
-        this.formChild.isSealed = 0;
-        this.formChild.remark = "";
-        this.formChild.parentId = row.id;
-        this.$refs.crudChild.rowAdd();
-      },
-      rowSave(row, done, loading) {
-        const form = {
-          ...row,
-          dictKey: -1,
-        };
-        add(form).then(() => {
+    handleAdd(row) {
+      this.formChild.dictValue = "";
+      this.formChild.dictKey = "";
+      this.formChild.sort = 0;
+      this.formChild.isSealed = 0;
+      this.formChild.remark = "";
+      this.formChild.parentId = row.id;
+      this.$refs.crudChild.rowAdd();
+    },
+    rowSave(row, done, loading) {
+      const form = {
+        ...row,
+        dictKey: -1,
+      };
+      add(form).then(
+        () => {
           this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowUpdate(row, index, done, loading) {
-        update(row).then(() => {
+        }
+      );
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(
+        () => {
           this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           this.onLoadChild(this.pageChild);
           done();
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowDel(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.onLoadParent(this.pageParent);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      handleRowClick(row) {
-        this.query = {};
-        this.parentId = row.id;
-        this.dictValue = row.dictValue;
-
-        const code = this.findObject(this.optionChild.column, "code");
-        code.value = row.code;
-        const parentId = this.findObject(this.optionChild.column, "parentId");
-        parentId.value = row.id;
-
-        this.box = true;
-        this.onLoadChild(this.pageChild);
-      },
-      searchReset() {
-        this.query = {};
-        this.onLoadParent(this.pageParent);
-      },
-      searchChange(params, done) {
-        this.query = params;
-        this.pageParent.currentPage = 1;
-        this.onLoadParent(this.pageParent, params);
-        done();
-      },
-      selectionChange(list) {
-        this.selectionList = list;
-      },
-      selectionClear() {
-        this.selectionList = [];
-        this.$refs.crud.toggleSelection();
-      },
-      handleDelete() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
         }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
+      );
+    },
+    rowDel(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
         })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            this.onLoadParent(this.pageParent);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crud.toggleSelection();
-          });
-      },
-      beforeOpen(done, type) {
-        if (["edit", "view"].includes(type)) {
-          getDict(this.formParent.id).then(res => {
-            this.formParent = res.data.data;
-          });
-        }
-        done();
-      },
-      currentChange(currentPage) {
-        this.pageParent.currentPage = currentPage;
-      },
-      sizeChange(pageSize) {
-        this.pageParent.pageSize = pageSize;
-      },
-      refreshChange() {
-        this.onLoadParent(this.pageParent, this.query);
-      },
-      rowSaveChild(row, done, loading) {
-        add(row).then(() => {
-          this.onLoadChild(this.pageChild);
+        .then(() => {
+          this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
-          done();
-        }, error => {
-          window.console.log(error);
-          loading();
         });
-      },
-      rowUpdateChild(row, index, done, loading) {
-        update(row).then(() => {
-          this.onLoadChild(this.pageChild);
+    },
+    handleRowClick(row) {
+      this.query = {};
+      this.parentId = row.id;
+      this.dictValue = row.dictValue;
+
+      const code = this.findObject(this.optionChild.column, "code");
+      code.value = row.code;
+      const parentId = this.findObject(this.optionChild.column, "parentId");
+      parentId.value = row.id;
+
+      this.box = true;
+      this.onLoadChild(this.pageChild);
+    },
+    searchReset() {
+      this.query = {};
+      this.onLoadParent(this.pageParent);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.pageParent.currentPage = 1;
+      this.onLoadParent(this.pageParent, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
+        })
+        .then(() => {
+          this.onLoadParent(this.pageParent);
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
-          done();
-        }, error => {
-          window.console.log(error);
-          loading();
+          this.$refs.crud.toggleSelection();
         });
-      },
-      rowDelChild(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.onLoadChild(this.pageChild);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      searchResetChild() {
-        this.query = {};
-        this.onLoadChild(this.pageChild);
-      },
-      searchChangeChild(params, done) {
-        this.query = params;
-        this.pageChild.currentPage = 1;
-        this.onLoadChild(this.pageChild, params);
-        done();
-      },
-      selectionChangeChild(list) {
-        this.selectionList = list;
-      },
-      selectionClearChild() {
-        this.selectionList = [];
-        this.$refs.crudChild.toggleSelection();
-      },
-      handleDeleteChild() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
-        }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            this.onLoadChild(this.pageChild);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crudChild.toggleSelection();
-          });
-      },
-      beforeOpenChild(done, type) {
-        if (["add", "edit"].includes(type)) {
-          this.initData();
-        }
-        if (["edit", "view"].includes(type)) {
-          getDict(this.formChild.id).then(res => {
-            this.formChild = res.data.data;
-          });
-        }
-        done();
-      },
-      beforeCloseChild(done) {
-        this.$refs.crudChild.value.parentId = this.parentId;
-        this.$refs.crudChild.option.column.filter(item => {
-          if (item.prop === "parentId") {
-            item.value = this.parentId;
-          }
-        });
-        done();
-      },
-      currentChangeChild(currentPage) {
-        this.pageChild.currentPage = currentPage;
-      },
-      sizeChangeChild(pageSize) {
-        this.pageChild.pageSize = pageSize;
-      },
-      refreshChangeChild() {
-        this.onLoadChild(this.pageChild, this.query);
-      },
-      onLoadParent(page, params = {}) {
-        this.loading = true;
-        getParentList(
-          page.currentPage,
-          page.pageSize,
-          Object.assign(params, this.query)
-        ).then(res => {
-          const data = res.data.data;
-          this.pageParent.total = data.total;
-          this.dataParent = data.records;
-          this.loading = false;
-          this.selectionClear();
-        });
-      },
-      onLoadChild(page, params = {}) {
-        this.loadingChild = true;
-        getChildList(
-          page.currentPage,
-          page.pageSize,
-          this.parentId,
-          Object.assign(params, this.query)
-        ).then(res => {
-          this.dataChild = res.data.data;
-          this.loadingChild = false;
-          this.selectionClear();
+    },
+    beforeOpen(done, type) {
+      if (["edit", "view"].includes(type)) {
+        getDict(this.formParent.id).then((res) => {
+          this.formParent = res.data.data;
         });
       }
-    }
-  };
+      done();
+    },
+    currentChange(currentPage) {
+      this.pageParent.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.pageParent.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoadParent(this.pageParent, this.query);
+    },
+    rowSaveChild(row, done, loading) {
+      add(row).then(
+        () => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
+    },
+    rowUpdateChild(row, index, done, loading) {
+      update(row).then(
+        () => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
+    },
+    rowDelChild(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
+        })
+        .then(() => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+        });
+    },
+    searchResetChild() {
+      this.query = {};
+      this.onLoadChild(this.pageChild);
+    },
+    searchChangeChild(params, done) {
+      this.query = params;
+      this.pageChild.currentPage = 1;
+      this.onLoadChild(this.pageChild, params);
+      done();
+    },
+    selectionChangeChild(list) {
+      this.selectionList = list;
+    },
+    selectionClearChild() {
+      this.selectionList = [];
+      this.$refs.crudChild.toggleSelection();
+    },
+    handleDeleteChild() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
+        })
+        .then(() => {
+          this.onLoadChild(this.pageChild);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.$refs.crudChild.toggleSelection();
+        });
+    },
+    beforeOpenChild(done, type) {
+      if (["add", "edit"].includes(type)) {
+        this.initData();
+      }
+      if (["edit", "view"].includes(type)) {
+        getDict(this.formChild.id).then((res) => {
+          this.formChild = res.data.data;
+        });
+      }
+      done();
+    },
+    beforeCloseChild(done) {
+      this.$refs.crudChild.value.parentId = this.parentId;
+      this.$refs.crudChild.option.column.filter((item) => {
+        if (item.prop === "parentId") {
+          item.value = this.parentId;
+        }
+      });
+      done();
+    },
+    currentChangeChild(currentPage) {
+      this.pageChild.currentPage = currentPage;
+    },
+    sizeChangeChild(pageSize) {
+      this.pageChild.pageSize = pageSize;
+    },
+    refreshChangeChild() {
+      this.onLoadChild(this.pageChild, this.query);
+    },
+    onLoadParent(page, params = {}) {
+      this.loading = true;
+      getParentList(
+        page.currentPage,
+        page.pageSize,
+        Object.assign(params, this.query)
+      ).then((res) => {
+        const data = res.data.data;
+        this.pageParent.total = data.total;
+        this.dataParent = data.records;
+        this.loading = false;
+        this.selectionClear();
+      });
+    },
+    onLoadChild(page, params = {}) {
+      this.loadingChild = true;
+      getChildList(
+        page.currentPage,
+        page.pageSize,
+        this.parentId,
+        Object.assign(params, this.query)
+      ).then((res) => {
+        this.dataChild = res.data.data;
+        this.loadingChild = false;
+        this.selectionClear();
+      });
+    },
+  },
+};
 </script>
diff --git a/src/views/system/menu.vue b/src/views/system/menu.vue
index b197c19..44bd669 100644
--- a/src/views/system/menu.vue
+++ b/src/views/system/menu.vue
@@ -1,31 +1,35 @@
 <template>
-  <basic-container>
-    <avue-crud :option="option"
-               :table-loading="loading"
-               :data="data"
-               ref="crud"
-               v-model="form"
-               :permission="permissionList"
-               :before-open="beforeOpen"
-               :before-close="beforeClose"
-               @row-del="rowDel"
-               @row-update="rowUpdate"
-               @row-save="rowSave"
-               @search-change="searchChange"
-               @search-reset="searchReset"
-               @selection-change="selectionChange"
-               @current-change="currentChange"
-               @size-change="sizeChange"
-               @refresh-change="refreshChange"
-               @on-load="onLoad"
-               @tree-load="treeLoad">
+  <basic-container class="hasButTwo">
+    <avue-crud
+      :option="option"
+      :table-loading="loading"
+      :data="data"
+      ref="crud"
+      v-model="form"
+      :permission="permissionList"
+      :before-open="beforeOpen"
+      :before-close="beforeClose"
+      @row-del="rowDel"
+      @row-update="rowUpdate"
+      @row-save="rowSave"
+      @search-change="searchChange"
+      @search-reset="searchReset"
+      @selection-change="selectionChange"
+      @current-change="currentChange"
+      @size-change="sizeChange"
+      @refresh-change="refreshChange"
+      @on-load="onLoad"
+      @tree-load="treeLoad"
+    >
       <template slot="menuLeft">
-        <el-button type="danger"
-                   size="small"
-                   icon="el-icon-delete"
-                   v-if="permission.menu_delete"
-                   plain
-                   @click="handleDelete">删 除
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          v-if="permission.menu_delete"
+          plain
+          @click="handleDelete"
+          >删 除
         </el-button>
       </template>
       <template slot-scope="scope" slot="menu">
@@ -33,15 +37,16 @@
           type="text"
           icon="el-icon-circle-plus-outline"
           size="small"
-          @click.stop="handleAdd(scope.row,scope.index)"
-          v-if="userInfo.role_name.includes('admin') && scope.row.category === 1"
-        >新增子项
+          @click.stop="handleAdd(scope.row, scope.index)"
+          v-if="
+            userInfo.role_name.includes('admin') && scope.row.category === 1
+          "
+          >新增子项
         </el-button>
       </template>
-      <template slot-scope="{row}"
-                slot="source">
-        <div style="text-align:center">
-          <i :class="row.source"/>
+      <template slot-scope="{ row }" slot="source">
+        <div style="text-align: center">
+          <i :class="row.source" />
         </div>
       </template>
     </avue-crud>
@@ -49,374 +54,382 @@
 </template>
 
 <script>
-  import {getLazyList, remove, update, add, getMenu} from "@/api/system/menu";
-  import {mapGetters} from "vuex";
-  import iconList from "@/config/iconList";
-  import func from "@/util/func";
-  import {getMenuTree} from "@/api/system/menu";
+import { getLazyList, remove, update, add, getMenu } from "@/api/system/menu";
+import { mapGetters } from "vuex";
+import iconList from "@/config/iconList";
+import func from "@/util/func";
+import { getMenuTree } from "@/api/system/menu";
 
-  export default {
-    data() {
-      return {
-        form: {},
-        query: {},
-        loading: true,
-        selectionList: [],
-        parentId: 0,
-        page: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0,
-        },
-        option: {
-          lazy: true,
-          tip: false,
-          simplePage: true,
-          searchShow: true,
-          searchMenuSpan: 6,
-          dialogWidth: "60%",
-          tree: true,
-          border: true,
-          index: true,
-          selection: true,
-          viewBtn: true,
-          menuWidth: 300,
-          dialogClickModal: false,
-          column: [
-            {
-              label: "菜单名称",
-              prop: "name",
-              search: true,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单名称",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "路由地址",
-              prop: "path",
-              rules: [
-                {
-                  required: true,
-                  message: "请输入路由地址",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "上级菜单",
-              prop: "parentId",
-              type: "tree",
-              dicData: [],
-              hide: true,
-              addDisabled: false,
-              props: {
-                label: "title"
+export default {
+  data() {
+    return {
+      form: {},
+      query: {},
+      loading: true,
+      selectionList: [],
+      parentId: 0,
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0,
+      },
+      option: {
+        lazy: true,
+        tip: false,
+        simplePage: true,
+        searchShow: true,
+        searchMenuSpan: 6,
+        dialogWidth: "60%",
+        tree: true,
+        border: true,
+        index: true,
+        selection: true,
+        viewBtn: true,
+        menuWidth: 300,
+        dialogClickModal: false,
+        column: [
+          {
+            label: "菜单名称",
+            prop: "name",
+            search: true,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单名称",
+                trigger: "blur",
               },
-              rules: [
-                {
-                  required: false,
-                  message: "请选择上级菜单",
-                  trigger: "click"
-                }
-              ]
+            ],
+          },
+          {
+            label: "路由地址",
+            prop: "path",
+            rules: [
+              {
+                required: true,
+                message: "请输入路由地址",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "上级菜单",
+            prop: "parentId",
+            type: "tree",
+            dicData: [],
+            hide: true,
+            addDisabled: false,
+            props: {
+              label: "title",
             },
-            {
-              label: "菜单图标",
-              prop: "source",
-              type: "icon",
-              slot: true,
-              iconList: iconList,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单图标",
-                  trigger: "click"
-                }
-              ]
-            },
-            {
-              label: "菜单编号",
-              prop: "code",
-              search: true,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单编号",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "菜单类型",
-              prop: "category",
-              type: "radio",
-              dicData: [
-                {
-                  label: "菜单",
-                  value: 1
-                },
-                {
-                  label: "按钮",
-                  value: 2
-                }
-              ],
-              hide: true,
-              rules: [
-                {
-                  required: true,
-                  message: "请选择菜单类型",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "菜单别名",
-              prop: "alias",
-              search: true,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单别名",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "新窗口",
-              prop: "isOpen",
-              type: "radio",
-              disabled: false,
-              dicData: [
-                {
-                  label: "否",
-                  value: 1
-                },
-                {
-                  label: "是",
-                  value: 2
-                }
-              ],
-              value: 1,
-              rules: [
-                {
-                  required: true,
-                  message: "请选择新窗口打开",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "菜单排序",
-              prop: "sort",
-              type: "number",
-              row: true,
-              span: 24,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单排序",
-                  trigger: "blur"
-                }
-              ]
-            },
-            {
-              label: "菜单备注",
-              prop: "remark",
-              type: "textarea",
-              span: 24,
-              minRows: 2,
-              hide: true
-            }
-          ]
-        },
-        data: []
+            rules: [
+              {
+                required: false,
+                message: "请选择上级菜单",
+                trigger: "click",
+              },
+            ],
+          },
+          {
+            label: "菜单图标",
+            prop: "source",
+            type: "icon",
+            slot: true,
+            iconList: iconList,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单图标",
+                trigger: "click",
+              },
+            ],
+          },
+          {
+            label: "菜单编号",
+            prop: "code",
+            search: true,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单编号",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单类型",
+            prop: "category",
+            type: "radio",
+            dicData: [
+              {
+                label: "菜单",
+                value: 1,
+              },
+              {
+                label: "按钮",
+                value: 2,
+              },
+            ],
+            hide: true,
+            rules: [
+              {
+                required: true,
+                message: "请选择菜单类型",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单别名",
+            prop: "alias",
+            search: true,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单别名",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "新窗口",
+            prop: "isOpen",
+            type: "radio",
+            disabled: false,
+            dicData: [
+              {
+                label: "否",
+                value: 1,
+              },
+              {
+                label: "是",
+                value: 2,
+              },
+            ],
+            value: 1,
+            rules: [
+              {
+                required: true,
+                message: "请选择新窗口打开",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单排序",
+            prop: "sort",
+            type: "number",
+            row: true,
+            span: 24,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单排序",
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单备注",
+            prop: "remark",
+            type: "textarea",
+            span: 24,
+            minRows: 2,
+            hide: true,
+          },
+        ],
+      },
+      data: [],
+    };
+  },
+  watch: {
+    "form.category"() {
+      const category = func.toInt(this.form.category);
+      this.$refs.crud.option.column.filter((item) => {
+        if (item.prop === "path") {
+          item.rules[0].required = category === 1;
+        }
+        if (item.prop === "isOpen") {
+          item.disabled = category === 2;
+        }
+      });
+    },
+  },
+  computed: {
+    ...mapGetters(["userInfo", "permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission.menu_add, false),
+        viewBtn: this.vaildData(this.permission.menu_view, false),
+        delBtn: this.vaildData(this.permission.menu_delete, false),
+        editBtn: this.vaildData(this.permission.menu_edit, false),
       };
     },
-    watch: {
-      'form.category'() {
-        const category = func.toInt(this.form.category);
-        this.$refs.crud.option.column.filter(item => {
-          if (item.prop === "path") {
-            item.rules[0].required = category === 1;
-          }
-          if (item.prop === 'isOpen') {
-            item.disabled = category === 2;
-          }
-        });
-      },
+    ids() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
     },
-    computed: {
-      ...mapGetters(["userInfo", "permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.menu_add, false),
-          viewBtn: this.vaildData(this.permission.menu_view, false),
-          delBtn: this.vaildData(this.permission.menu_delete, false),
-          editBtn: this.vaildData(this.permission.menu_edit, false)
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
-      }
-    },
-    methods: {
-      initData() {
-        getMenuTree().then(res => {
-          const column = this.findObject(this.option.column, "parentId");
-          column.dicData = res.data.data;
-        });
-      },
-      handleAdd(row) {
-        this.parentId = row.id;
+  },
+  methods: {
+    initData() {
+      getMenuTree().then((res) => {
         const column = this.findObject(this.option.column, "parentId");
-        column.value = row.id;
-        column.addDisabled = true;
-        this.$refs.crud.rowAdd();
-      },
-      rowSave(row, done, loading) {
-        add(row).then((res) => {
+        column.dicData = res.data.data;
+      });
+    },
+    handleAdd(row) {
+      this.parentId = row.id;
+      const column = this.findObject(this.option.column, "parentId");
+      column.value = row.id;
+      column.addDisabled = true;
+      this.$refs.crud.rowAdd();
+    },
+    rowSave(row, done, loading) {
+      add(row).then(
+        (res) => {
           // 获取新增数据的相关字段
           const data = res.data.data;
           row.id = data.id;
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           // 数据回调进行刷新
           done(row);
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
-        });
-      },
-      rowUpdate(row, index, done, loading) {
-        update(row).then(() => {
+        }
+      );
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(
+        () => {
           this.$message({
             type: "success",
-            message: "操作成功!"
+            message: "操作成功!",
           });
           // 数据回调进行刷新
           done(row);
-        }, error => {
+        },
+        (error) => {
           window.console.log(error);
           loading();
+        }
+      );
+    },
+    rowDel(row, index, done) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
+        })
+        .then(() => {
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          // 数据回调进行刷新
+          done(row);
         });
-      },
-      rowDel(row, index, done) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
         })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            // 数据回调进行刷新
-            done(row);
+        .then(() => {
+          // 刷新表格数据并重载
+          this.data = [];
+          this.parentId = 0;
+          this.$refs.crud.refreshTable();
+          this.$refs.crud.toggleSelection();
+          // 表格数据重载
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
           });
-      },
-      handleDelete() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
-        }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            // 刷新表格数据并重载
-            this.data = [];
-            this.parentId = 0;
-            this.$refs.crud.refreshTable();
-            this.$refs.crud.toggleSelection();
-            // 表格数据重载
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      searchReset() {
-        this.query = {};
-        this.parentId = 0;
-        this.onLoad(this.page);
-      },
-      searchChange(params, done) {
-        this.query = params;
-        this.parentId = '';
-        this.page.currentPage = 1;
-        this.onLoad(this.page, params);
-        done();
-      },
-      selectionChange(list) {
-        this.selectionList = list;
-      },
-      selectionClear() {
-        this.selectionList = [];
-        this.$refs.crud.toggleSelection();
-      },
-      beforeOpen(done, type) {
-        if (["add", "edit"].includes(type)) {
-          this.initData();
-        }
-        if (["edit", "view"].includes(type)) {
-          getMenu(this.form.id).then(res => {
-            this.form = res.data.data;
-          });
-        }
-        done();
-      },
-      beforeClose(done) {
-        this.parentId = "";
-        const column = this.findObject(this.option.column, "parentId");
-        column.value = "";
-        column.addDisabled = false;
-        done();
-      },
-      currentChange(currentPage) {
-        this.page.currentPage = currentPage;
-      },
-      sizeChange(pageSize) {
-        this.page.pageSize = pageSize;
-      },
-      refreshChange() {
-        this.onLoad(this.page, this.query);
-      },
-      onLoad(page, params = {}) {
-        this.loading = true;
-        getLazyList(this.parentId, Object.assign(params, this.query)).then(res => {
+        });
+    },
+    searchReset() {
+      this.query = {};
+      this.parentId = 0;
+      this.onLoad(this.page);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.parentId = "";
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    beforeOpen(done, type) {
+      if (["add", "edit"].includes(type)) {
+        this.initData();
+      }
+      if (["edit", "view"].includes(type)) {
+        getMenu(this.form.id).then((res) => {
+          this.form = res.data.data;
+        });
+      }
+      done();
+    },
+    beforeClose(done) {
+      this.parentId = "";
+      const column = this.findObject(this.option.column, "parentId");
+      column.value = "";
+      column.addDisabled = false;
+      done();
+    },
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoad(this.page, this.query);
+    },
+    onLoad(page, params = {}) {
+      this.loading = true;
+      getLazyList(this.parentId, Object.assign(params, this.query)).then(
+        (res) => {
           this.data = res.data.data;
           this.loading = false;
           this.selectionClear();
-        });
-      },
-      treeLoad(tree, treeNode, resolve) {
-        const parentId = tree.id;
-        getLazyList(parentId).then(res => {
-          resolve(res.data.data);
-        });
-      }
-    }
-  };
+        }
+      );
+    },
+    treeLoad(tree, treeNode, resolve) {
+      const parentId = tree.id;
+      getLazyList(parentId).then((res) => {
+        resolve(res.data.data);
+      });
+    },
+  },
+};
 </script>
 
 <style>
diff --git a/src/views/system/topmenu.vue b/src/views/system/topmenu.vue
index fdb6388..934883d 100644
--- a/src/views/system/topmenu.vue
+++ b/src/views/system/topmenu.vue
@@ -1,332 +1,371 @@
 <template>
-  <basic-container>
-    <avue-crud :option="option"
-               :table-loading="loading"
-               :data="data"
-               :page.sync="page"
-               :permission="permissionList"
-               :before-open="beforeOpen"
-               v-model="form"
-               ref="crud"
-               @row-update="rowUpdate"
-               @row-save="rowSave"
-               @row-del="rowDel"
-               @search-change="searchChange"
-               @search-reset="searchReset"
-               @selection-change="selectionChange"
-               @current-change="currentChange"
-               @size-change="sizeChange"
-               @refresh-change="refreshChange"
-               @on-load="onLoad">
+  <basic-container class="topmenu">
+    <avue-crud
+      :option="option"
+      :table-loading="loading"
+      :data="data"
+      :page.sync="page"
+      :permission="permissionList"
+      :before-open="beforeOpen"
+      v-model="form"
+      ref="crud"
+      @row-update="rowUpdate"
+      @row-save="rowSave"
+      @row-del="rowDel"
+      @search-change="searchChange"
+      @search-reset="searchReset"
+      @selection-change="selectionChange"
+      @current-change="currentChange"
+      @size-change="sizeChange"
+      @refresh-change="refreshChange"
+      @on-load="onLoad"
+    >
       <template slot="menuLeft">
-        <el-button type="danger"
-                   size="small"
-                   icon="el-icon-delete"
-                   plain
-                   v-if="permission.topmenu_delete"
-                   @click="handleDelete">删 除
+        <el-button
+          type="danger"
+          size="small"
+          icon="el-icon-delete"
+          plain
+          v-if="permission.topmenu_delete"
+          @click="handleDelete"
+          >删 除
         </el-button>
-        <el-button size="small"
-                   icon="el-icon-delete"
-                   @click="handleMenuSetting"
-                   v-if="permission.topmenu_setting"
-                   plain>菜单配置
+        <el-button
+          size="small"
+          icon="el-icon-delete"
+          @click="handleMenuSetting"
+          v-if="permission.topmenu_setting"
+          plain
+          >菜单配置
         </el-button>
       </template>
-      <template slot-scope="{row}" slot="source">
-        <div style="text-align:center">
+      <template slot-scope="{ row }" slot="source">
+        <div style="text-align: center">
           <i :class="row.source"></i>
         </div>
       </template>
-      <template slot="sort" slot-scope="{row}" >
-        <el-input-number v-model="row.sort" @change="sortChange(row)" :min="1" :max="100"></el-input-number>
+      <template slot="sort" slot-scope="{ row }">
+        <el-input-number
+          v-model="row.sort"
+          @change="sortChange(row)"
+          :min="1"
+          :max="100"
+        ></el-input-number>
       </template>
     </avue-crud>
-    <el-dialog title="下级菜单配置"
-               append-to-body
-               :visible.sync="box"
-               width="345px">
-
-      <el-tree :data="menuGrantList"
-               show-checkbox
-               node-key="id"
-               ref="treeMenu"
-               :default-checked-keys="menuTreeObj"
-               :props="props">
+    <el-dialog
+      title="下级菜单配置"
+      append-to-body
+      :visible.sync="box"
+      width="345px"
+    >
+      <el-tree
+        :data="menuGrantList"
+        show-checkbox
+        node-key="id"
+        ref="treeMenu"
+        :default-checked-keys="menuTreeObj"
+        :props="props"
+      >
       </el-tree>
 
-      <span slot="footer"
-            class="dialog-footer">
+      <span slot="footer" class="dialog-footer">
         <el-button @click="box = false">取 消</el-button>
-        <el-button type="primary"
-                   @click="submit">确 定</el-button>
+        <el-button type="primary" @click="submit">确 定</el-button>
       </span>
     </el-dialog>
   </basic-container>
 </template>
 
 <script>
-  import {getList, getDetail, add, update, remove, grant, grantTree, getTopTree} from "@/api/system/topmenu";
-  import {mapGetters} from "vuex";
-  import iconList from "@/config/iconList";
+import {
+  getList,
+  getDetail,
+  add,
+  update,
+  remove,
+  grant,
+  grantTree,
+  getTopTree,
+} from "@/api/system/topmenu";
+import { mapGetters } from "vuex";
+import iconList from "@/config/iconList";
 
-  export default {
-    data() {
-      return {
-        form: {},
-        box: false,
-        query: {},
-        loading: true,
-        props: {
-          label: "title",
-          value: "key"
-        },
-        page: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0
-        },
-        selectionList: [],
-        menuGrantList: [],
-        menuTreeObj: [],
-        option: {
-          height: 'auto',
-          calcHeight: 30,
-          tip: false,
-          searchShow: true,
-          searchMenuSpan: 6,
-          border: true,
-          index: true,
-          viewBtn: true,
-          selection: true,
-          dialogWidth: 900,
-          dialogClickModal: false,
-          column: [
-            {
-              label: "菜单名",
-              prop: "name",
-              search: true,
-              rules: [{
+export default {
+  data() {
+    return {
+      form: {},
+      box: false,
+      query: {},
+      loading: true,
+      props: {
+        label: "title",
+        value: "key",
+      },
+      page: {
+        pageSize: 10,
+        currentPage: 1,
+        total: 0,
+      },
+      selectionList: [],
+      menuGrantList: [],
+      menuTreeObj: [],
+      option: {
+        height: "auto",
+        calcHeight: 30,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 6,
+        border: true,
+        index: true,
+        viewBtn: true,
+        selection: true,
+        dialogWidth: 900,
+        dialogClickModal: false,
+        column: [
+          {
+            label: "菜单名",
+            prop: "name",
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入菜单名",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "菜单图标",
-              prop: "source",
-              type: "icon",
-              slot: true,
-              iconList: iconList,
-              rules: [
-                {
-                  required: true,
-                  message: "请输入菜单图标",
-                  trigger: "click"
-                }
-              ]
-            },
-            {
-              label: "菜单编号",
-              prop: "code",
-              search: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单图标",
+            prop: "source",
+            type: "icon",
+            slot: true,
+            iconList: iconList,
+            rules: [
+              {
+                required: true,
+                message: "请输入菜单图标",
+                trigger: "click",
+              },
+            ],
+          },
+          {
+            label: "菜单编号",
+            prop: "code",
+            search: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入菜单编号",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "菜单排序",
-              prop: "sort",
-              type: "number",
-              slot: true,
-              rules: [{
+                trigger: "blur",
+              },
+            ],
+          },
+          {
+            label: "菜单排序",
+            prop: "sort",
+            type: "number",
+            slot: true,
+            rules: [
+              {
                 required: true,
                 message: "请输入菜单排序",
-                trigger: "blur"
-              }]
-            },
-          ]
-        },
-        data: []
+                trigger: "blur",
+              },
+            ],
+          },
+        ],
+      },
+      data: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["permission"]),
+    permissionList() {
+      return {
+        addBtn: this.vaildData(this.permission.topmenu_add, false),
+        viewBtn: this.vaildData(this.permission.topmenu_view, false),
+        delBtn: this.vaildData(this.permission.topmenu_delete, false),
+        editBtn: this.vaildData(this.permission.topmenu_edit, false),
       };
     },
-    computed: {
-      ...mapGetters(["permission"]),
-      permissionList() {
-        return {
-          addBtn: this.vaildData(this.permission.topmenu_add, false),
-          viewBtn: this.vaildData(this.permission.topmenu_view, false),
-          delBtn: this.vaildData(this.permission.topmenu_delete, false),
-          editBtn: this.vaildData(this.permission.topmenu_edit, false)
-        };
-      },
-      ids() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
-      },
-      idsArray() {
-        let ids = [];
-        this.selectionList.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids;
-      }
+    ids() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids.join(",");
     },
-    methods: {
-      submit() {
-        const menuList = this.$refs.treeMenu.getCheckedKeys();
-        grant(this.idsArray, menuList).then(() => {
-          this.box = false;
-          this.$message({
-            type: "success",
-            message: "操作成功!"
-          });
-          this.onLoad(this.page);
+    idsArray() {
+      let ids = [];
+      this.selectionList.forEach((ele) => {
+        ids.push(ele.id);
+      });
+      return ids;
+    },
+  },
+  methods: {
+    submit() {
+      const menuList = this.$refs.treeMenu.getCheckedKeys();
+      grant(this.idsArray, menuList).then(() => {
+        this.box = false;
+        this.$message({
+          type: "success",
+          message: "操作成功!",
         });
-      },
-      rowSave(row, done, loading) {
-        add(row).then(() => {
-          this.onLoad(this.page);
-          this.$message({
-            type: "success",
-            message: "操作成功!"
-          });
-          done();
-        }, error => {
-          window.console.log(error);
-          loading();
-        });
-      },
-      rowUpdate(row, index, done, loading) {
-        update(row).then(() => {
-          this.onLoad(this.page);
-          this.$message({
-            type: "success",
-            message: "操作成功!"
-          });
-          done();
-        }, error => {
-          window.console.log(error);
-          loading();
-        });
-      },
-      rowDel(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(row.id);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      handleDelete() {
-        if (this.selectionList.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
-        }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return remove(this.ids);
-          })
-          .then(() => {
-            this.onLoad(this.page);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crud.toggleSelection();
-          });
-      },
-      handleMenuSetting() {
-        if (this.selectionList.length !== 1) {
-          this.$message.warning("只能选择一条数据");
-          return;
-        }
-        this.menuTreeObj = [];
-        grantTree()
-          .then(res => {
-            this.menuGrantList = res.data.data.menu;
-            getTopTree(this.ids).then(res => {
-              this.menuTreeObj = res.data.data.menu;
-              this.box = true;
-            });
-          });
-      },
-      beforeOpen(done, type) {
-        if (["edit", "view"].includes(type)) {
-          getDetail(this.form.id).then(res => {
-            this.form = res.data.data;
-          });
-        }
-        done();
-      },
-      sortChange(row) {
-        update(row).then(() => {
-          this.onLoad(this.page);
-        }, error => {
-          window.console.log(error);
-        });
-      },
-      searchReset() {
-        this.query = {};
         this.onLoad(this.page);
-      },
-      searchChange(params, done) {
-        this.query = params;
-        this.page.currentPage = 1;
-        this.onLoad(this.page, params);
-        done();
-      },
-      selectionChange(list) {
-        this.selectionList = list;
-      },
-      selectionClear() {
-        this.selectionList = [];
-        this.$refs.crud.toggleSelection();
-      },
-      currentChange(currentPage) {
-        this.page.currentPage = currentPage;
-      },
-      sizeChange(pageSize) {
-        this.page.pageSize = pageSize;
-      },
-      refreshChange() {
-        this.onLoad(this.page, this.query);
-      },
-      onLoad(page, params = {}) {
-        this.loading = true;
-        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
-          const data = res.data.data;
-          this.page.total = data.total;
-          this.data = data.records;
-          this.loading = false;
-          this.selectionClear();
+      });
+    },
+    rowSave(row, done, loading) {
+      add(row).then(
+        () => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
+    },
+    rowUpdate(row, index, done, loading) {
+      update(row).then(
+        () => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          done();
+        },
+        (error) => {
+          window.console.log(error);
+          loading();
+        }
+      );
+    },
+    rowDel(row) {
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(row.id);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+        });
+    },
+    handleDelete() {
+      if (this.selectionList.length === 0) {
+        this.$message.warning("请选择至少一条数据");
+        return;
+      }
+      this.$confirm("确定将选择数据删除?", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          return remove(this.ids);
+        })
+        .then(() => {
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!",
+          });
+          this.$refs.crud.toggleSelection();
+        });
+    },
+    handleMenuSetting() {
+      if (this.selectionList.length !== 1) {
+        this.$message.warning("只能选择一条数据");
+        return;
+      }
+      this.menuTreeObj = [];
+      grantTree().then((res) => {
+        this.menuGrantList = res.data.data.menu;
+        getTopTree(this.ids).then((res) => {
+          this.menuTreeObj = res.data.data.menu;
+          this.box = true;
+        });
+      });
+    },
+    beforeOpen(done, type) {
+      if (["edit", "view"].includes(type)) {
+        getDetail(this.form.id).then((res) => {
+          this.form = res.data.data;
         });
       }
-    }
-  };
+      done();
+    },
+    sortChange(row) {
+      update(row).then(
+        () => {
+          this.onLoad(this.page);
+        },
+        (error) => {
+          window.console.log(error);
+        }
+      );
+    },
+    searchReset() {
+      this.query = {};
+      this.onLoad(this.page);
+    },
+    searchChange(params, done) {
+      this.query = params;
+      this.page.currentPage = 1;
+      this.onLoad(this.page, params);
+      done();
+    },
+    selectionChange(list) {
+      this.selectionList = list;
+    },
+    selectionClear() {
+      this.selectionList = [];
+      this.$refs.crud.toggleSelection();
+    },
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage;
+    },
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize;
+    },
+    refreshChange() {
+      this.onLoad(this.page, this.query);
+    },
+    onLoad(page, params = {}) {
+      this.loading = true;
+      getList(
+        page.currentPage,
+        page.pageSize,
+        Object.assign(params, this.query)
+      ).then((res) => {
+        const data = res.data.data;
+        this.page.total = data.total;
+        this.data = data.records;
+        this.loading = false;
+        this.selectionClear();
+      });
+    },
+  },
+};
 </script>
 
 <style>
-  .none-border {
-    border: 0;
-    background-color: transparent !important;
-  }
+.none-border {
+  border: 0;
+  background-color: transparent !important;
+}
 </style>
diff --git a/src/views/system/user.vue b/src/views/system/user.vue
index d0f5ff0..ccfbd2a 100644
--- a/src/views/system/user.vue
+++ b/src/views/system/user.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-row>
+  <el-row class="user">
     <el-col :span="5">
       <div class="box">
         <el-scrollbar>
diff --git a/src/views/trainingRegistration/index.vue b/src/views/trainingRegistration/index.vue
index 35387c0..dddcc75 100644
--- a/src/views/trainingRegistration/index.vue
+++ b/src/views/trainingRegistration/index.vue
@@ -64,12 +64,13 @@
         tip: false,
         searchSize: "mini",
         searchMenuSpan: 6,
-        height: 627,
+        height: 693,
+        index: true,
         menuWidth: 290,
         align: "center",
         selection: true,
         column: column,
-        delBtn: false
+        delBtn: false,
       },
     };
   },
diff --git a/src/views/workreport/data.js b/src/views/workreport/data.js
index eccf4d0..9d36645 100644
--- a/src/views/workreport/data.js
+++ b/src/views/workreport/data.js
@@ -1,230 +1,230 @@
 //已发送列表信息
 export var workreportColumn = [{
-        label: "汇报时间",
-        prop: "reportTime",
-        type: "datetime",
-        format: "yyyy-MM-dd HH:mm:ss",
-        valueFormat: "yyyy-MM-dd HH:mm:ss",
-        searchRange: true,
-        searchSpan: 6,
-        hide: false,
-        addDisplay: false,
-        editDisplay: false,
-        // viewDisplay: false,
-        search: false,
-        rules: [{
-            required: true,
-            message: "请输入时间",
-            trigger: "blur"
-        }]
-    }, {
-        label: "汇报类别",
-        prop: "category",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportCategory",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        searchSpan: 4,
-        search: true,
-        rules: [{
-            required: true,
-            message: "请选择汇报类别",
-            trigger: "blur"
-        }]
-    }, {
-        label: "汇报类型",
-        prop: "type",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportType",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        searchSpan: 4,
-        search: true,
-        rules: [{
-            required: true,
-            message: "请选择汇报类型",
-            trigger: "blur"
-        }]
+    label: "汇报时间",
+    prop: "reportTime",
+    type: "datetime",
+    format: "yyyy-MM-dd HH:mm:ss",
+    valueFormat: "yyyy-MM-dd HH:mm:ss",
+    searchRange: true,
+    searchSpan: 6,
+    hide: false,
+    addDisplay: false,
+    editDisplay: false,
+    // viewDisplay: false,
+    search: false,
+    rules: [{
+        required: true,
+        message: "请输入时间",
+        trigger: "blur"
+    }]
+}, {
+    label: "汇报类别",
+    prop: "category",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportCategory",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "汇报人身份证号",
-        prop: "idCardNo",
-        hide: true,
-        addDisplay: false,
-        editDisplay: false,
-        viewDisplay: false,
+    dataType: "number",
+    searchSpan: 5,
+    search: true,
+    rules: [{
+        required: true,
+        message: "请选择汇报类别",
+        trigger: "blur"
+    }]
+}, {
+    label: "汇报类型",
+    prop: "type",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportType",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "汇报内容",
-        prop: "content",
-        type: "textarea",
-        span: 24,
-        rules: [{
-            required: true,
-            message: "请输入汇报内容",
-            trigger: "blur"
-        }]
+    dataType: "number",
+    searchSpan: 5,
+    search: true,
+    rules: [{
+        required: true,
+        message: "请选择汇报类型",
+        trigger: "blur"
+    }]
+},
+{
+    label: "汇报人身份证号",
+    prop: "idCardNo",
+    hide: true,
+    addDisplay: false,
+    editDisplay: false,
+    viewDisplay: false,
+},
+{
+    label: "汇报内容",
+    prop: "content",
+    type: "textarea",
+    span: 24,
+    rules: [{
+        required: true,
+        message: "请输入汇报内容",
+        trigger: "blur"
+    }]
+},
+{
+    label: "接收人",
+    prop: "receivedIds",
+    span: 24,
+    type: "tree",
+    dicUrl: "/api/blade-system/dept/lazy-tree-user",
+    hide: true,
+    props: {
+        label: "title",
+        value: "id",
     },
-    {
-        label: "接收人",
-        prop: "receivedIds",
-        span: 24,
-        type: "tree",
-        dicUrl: "/api/blade-system/dept/lazy-tree-user",
-        hide: true,
-        props: {
-            label: "title",
-            value: "id",
-        },
-        multiple: true,
-        // dataType: "number",
-        rules: [{
-            required: true,
-            message: "请选择接收人",
-            trigger: "blur"
-        }]
-    },
-    {
-        label: "接收人",
-        prop: "replyRealName",
-        addDisplay: false,
-        editDisplay: false,
-        viewDisplay: false,
-    },
-    {
-        label: "接收人单位",
-        prop: "replyDeptName",
-        addDisplay: false,
-        editDisplay: false,
-        // viewDisplay: false,
-    },
-    {
-        label: "回复内容",
-        prop: "replyContent",
-        type: "textarea",
-        span: 24,
-        addDisplay: false,
-        editDisplay: false,
-        rules: [{
-            required: true,
-            message: "请输入回复内容",
-            trigger: "blur"
-        }]
-    }
+    multiple: true,
+    // dataType: "number",
+    rules: [{
+        required: true,
+        message: "请选择接收人",
+        trigger: "blur"
+    }]
+},
+{
+    label: "接收人",
+    prop: "replyRealName",
+    addDisplay: false,
+    editDisplay: false,
+    viewDisplay: false,
+},
+{
+    label: "接收人单位",
+    prop: "replyDeptName",
+    addDisplay: false,
+    editDisplay: false,
+    // viewDisplay: false,
+},
+{
+    label: "回复内容",
+    prop: "replyContent",
+    type: "textarea",
+    span: 24,
+    addDisplay: false,
+    editDisplay: false,
+    rules: [{
+        required: true,
+        message: "请输入回复内容",
+        trigger: "blur"
+    }]
+}
 ]
 
 
 //接收人列信息
 export var workreplyColumn = [{
-        label: "汇报人",
-        prop: "realName",
-        disabled: true,
-        span: 24,
-        rules: [{
-            required: true,
-            message: "请选择接收人",
-            trigger: "blur"
-        }]
+    label: "汇报人",
+    prop: "realName",
+    disabled: true,
+    span: 24,
+    rules: [{
+        required: true,
+        message: "请选择接收人",
+        trigger: "blur"
+    }]
+},
+{
+    label: "汇报人单位",
+    prop: "deptName",
+    addDisplay: false,
+    editDisplay: false,
+    // viewDisplay: false,
+}, {
+    label: "汇报时间",
+    prop: "reportTime",
+    type: "datetime",
+    format: "yyyy-MM-dd HH:mm:ss",
+    valueFormat: "yyyy-MM-dd HH:mm:ss",
+    searchRange: true,
+    searchSpan: 6,
+    hide: false,
+    addDisplay: false,
+    editDisplay: false,
+    // viewDisplay: false,
+    search: false,
+    rules: [{
+        required: true,
+        message: "请输入时间",
+        trigger: "blur"
+    }]
+}, {
+    label: "汇报类别",
+    prop: "category",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportCategory",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    {
-        label: "汇报人单位",
-        prop: "deptName",
-        addDisplay: false,
-        editDisplay: false,
-        // viewDisplay: false,
-    }, {
-        label: "汇报时间",
-        prop: "reportTime",
-        type: "datetime",
-        format: "yyyy-MM-dd HH:mm:ss",
-        valueFormat: "yyyy-MM-dd HH:mm:ss",
-        searchRange: true,
-        searchSpan: 6,
-        hide: false,
-        addDisplay: false,
-        editDisplay: false,
-        // viewDisplay: false,
-        search: false,
-        rules: [{
-            required: true,
-            message: "请输入时间",
-            trigger: "blur"
-        }]
-    }, {
-        label: "汇报类别",
-        prop: "category",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportCategory",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        searchSpan: 4,
-        search: true,
-        hide: true,
-        editDisplay: false,
-        rules: [{
-            required: true,
-            message: "请选择汇报类别",
-            trigger: "blur"
-        }]
-    }, {
-        label: "汇报类型",
-        prop: "type",
-        type: "select",
-        dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportType",
-        props: {
-            label: "dictValue",
-            value: "dictKey"
-        },
-        dataType: "number",
-        searchSpan: 4,
-        search: true,
-        disabled: true,
-        rules: [{
-            required: true,
-            message: "请选择汇报类型",
-            trigger: "blur"
-        }]
+    dataType: "number",
+    searchSpan: 4,
+    search: true,
+    hide: true,
+    editDisplay: false,
+    rules: [{
+        required: true,
+        message: "请选择汇报类别",
+        trigger: "blur"
+    }]
+}, {
+    label: "汇报类型",
+    prop: "type",
+    type: "select",
+    dicUrl: "/api/blade-system/dict-biz/dictionary?code=workReportType",
+    props: {
+        label: "dictValue",
+        value: "dictKey"
     },
-    // {
-    //     label: "汇报人身份证号",
-    //     prop: "idCardNo",
-    //     hide: true,
-    //     addDisplay: false,
-    //     editDisplay: false,
-    //     viewDisplay: false,
-    // },
-    {
-        label: "汇报内容",
-        prop: "content",
-        type: "textarea",
-        // editDisplay: false,
-        disabled: true,
-        span: 24,
-        rules: [{
-            required: true,
-            message: "请输入汇报内容",
-            trigger: "blur"
-        }]
-    },
-    {
-        label: "回复内容",
-        prop: "replyContent",
-        type: "textarea",
-        span: 24,
-        rules: [{
-            required: true,
-            message: "请输入回复内容",
-            trigger: "blur"
-        }]
-    }
+    dataType: "number",
+    searchSpan: 4,
+    search: true,
+    disabled: true,
+    rules: [{
+        required: true,
+        message: "请选择汇报类型",
+        trigger: "blur"
+    }]
+},
+// {
+//     label: "汇报人身份证号",
+//     prop: "idCardNo",
+//     hide: true,
+//     addDisplay: false,
+//     editDisplay: false,
+//     viewDisplay: false,
+// },
+{
+    label: "汇报内容",
+    prop: "content",
+    type: "textarea",
+    // editDisplay: false,
+    disabled: true,
+    span: 24,
+    rules: [{
+        required: true,
+        message: "请输入汇报内容",
+        trigger: "blur"
+    }]
+},
+{
+    label: "回复内容",
+    prop: "replyContent",
+    type: "textarea",
+    span: 24,
+    rules: [{
+        required: true,
+        message: "请输入回复内容",
+        trigger: "blur"
+    }]
+}
 
 ]
\ No newline at end of file
diff --git a/src/views/workreport/workreport.vue b/src/views/workreport/workreport.vue
index d1ca951..8ad6a38 100644
--- a/src/views/workreport/workreport.vue
+++ b/src/views/workreport/workreport.vue
@@ -1,5 +1,5 @@
 <template>
-  <basic-container>
+  <basic-container class="workreply">
     <avue-crud
       :option="option"
       :table-loading="loading"
@@ -271,4 +271,8 @@
 </script>
 
 <style>
+.workreply .el-card.is-never-shadow.avue-crud__search {
+  width: calc(100% - 380px) !important;
+  left: 200px !important;
+}
 </style>

--
Gitblit v1.9.3