Browse Source

Merge branch 'main' into feature_check

weijin 4 years ago
parent
commit
9efcc81e49

+ 0 - 60
src/components/HelloWorld.vue

@@ -1,60 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br>
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
-      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
-      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
-      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
-      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'HelloWorld',
-  props: {
-    msg: String
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
-</style>

+ 74 - 73
src/components/QuestionCard/PrimaryQuestionCard.vue

@@ -4,18 +4,17 @@
       <!--      <el-space>-->
       <el-space style="display: flex">
         <span><strong>S/N: </strong>{{ curNum + 1 }} / {{ totalNum }}</span>
-        <span><strong>题目类型: </strong>{{ questionVO.type }}</span>
-        <el-button type="text" circle @click="isAllShow=!isAllShow"><strong>{{ isAllShowText }}</strong></el-button>
+        <span style="margin-left: 20px"><strong>题目类型: </strong>{{ questionVO.type }}</span>
+        <span style="margin-left: 20px"><strong>知识点: </strong></span>
         <div>
           <!--知识点插槽,用于更新题目卡片中可能存在的知识点改变差异-->
           <slot name="knowledgeId">
-            <span><strong>KnowledgeId: </strong></span>
             <!--知识点显示内容-->
             <el-tooltip
-              v-if="questionVO.knowledgeId && questionVO.knowledgeId.length !== 0"
-              v-for="item in questionVO.knowledgeId"
-              effect="dark"
-              placement="bottom">
+                v-if="questionVO.knowledgeId && questionVO.knowledgeId.length !== 0"
+                v-for="item in questionVO.knowledgeId"
+                effect="dark"
+                placement="bottom">
               <template #content>
                 {{ map(item) }}
               </template>
@@ -24,13 +23,14 @@
             <span v-else>null</span>
           </slot>
         </div>
+        <el-button type="text" circle @click="isAllShow=!isAllShow"><strong>{{ isAllShowText }}</strong></el-button>
+        <slot name="button">
+          <!--按钮插槽,用于不同的卡片更换不同的按钮-->
+          <el-button type="primary" icon="el-icon-edit" circle @click="updateQuestion"/>
+          <el-button v-if="isDelete === false" type="danger" icon="el-icon-delete" circle @click="deleteQuestion"/>
+          <el-button v-else type="success" icon="el-icon-delete" circle @click="recoverQuestion"/>
+        </slot>
       </el-space>
-      <slot name="button">
-        <!--按钮插槽,用于不同的卡片更换不同的按钮-->
-        <el-button type="primary" icon="el-icon-edit" circle @click="updateQuestion"/>
-        <el-button v-if="isDelete === false" type="danger" icon="el-icon-delete" circle @click="deleteQuestion"/>
-        <el-button v-else type="success" icon="el-icon-delete" circle @click="recoverQuestion"/>
-      </slot>
       <!--      </el-space>-->
     </template>
     <!--题目内容部分-->
@@ -67,32 +67,32 @@
       <div class="analysis-block">
         <el-row>
           <slot name="keypoint">
-            <el-col :span="10">
-              <strong>KeyPoints: </strong>{{ questionVO.keyPoints }}
+            <el-col :span="6" style="text-align: left">
+              <strong>关键词: </strong>{{ questionVO.keyPoints ? questionVO.keyPoints : '无' }}
             </el-col>
           </slot>
           <slot name="difficulty">
-            <el-col :span="6">
+            <el-col :span="6" style="text-align: left">
               <strong>题目难度: </strong>{{ questionVO.weight }}/5
             </el-col>
           </slot>
           <slot name="tag">
-            <el-col :span="4">
-              <span><strong>Tags: </strong></span>
+            <el-col :span="12" style="text-align: left">
+              <span><strong>标签: </strong></span>
               <span v-if="questionVO.tags && questionVO.tags.length !== 0">
-              <el-tag v-for="(item, index) in questionVO.tags" effect="dark">
-                {{ item }}
-              </el-tag>
-            </span>
+                <el-tag v-for="(item, index) in questionVO.tags" effect="dark">
+                  {{ item }}
+                </el-tag>
+              </span>
               <span v-else>
-              <span>no tags</span>
+              <span><el-tag effect="dark">无</el-tag></span>
             </span>
             </el-col>
           </slot>
         </el-row>
       </div>
       <!--题目解析-正确答案-->
-      <div class="analysis-block">
+      <div class="analysis-block" style="text-align: left">
         <!--单选、多选、判断、简单-->
         <slot name="answer1"
               v-if="questionVO.type === 'choice' ||
@@ -104,7 +104,7 @@
         <!--todo: 简答-->
       </div>
       <!--题目解析-解析部分-->
-      <div class="analysis-block">
+      <div class="analysis-block" style="text-align: left">
         <!--单选、多选、判断-->
         <slot name="analysis1"
               v-if="questionVO.type === 'choice' ||
@@ -152,17 +152,17 @@
     </div>
   </el-card>
 
-  <el-drawer
-    title="更新题目"
-    :before-close="handleClose"
-    v-model="dialog"
-    direction="rtl"
-    custom-class="question-drawer"
-    ref="drawer"
-    size="35%"
-  >
-    <QuestionUpdater :question="questionVO" @closeDialog="closeDialog"/>
-  </el-drawer>
+  <!--  <el-drawer-->
+  <!--    title="更新题目"-->
+  <!--    :before-close="handleClose"-->
+  <!--    v-model="dialog"-->
+  <!--    direction="rtl"-->
+  <!--    custom-class="question-drawer"-->
+  <!--    ref="drawer"-->
+  <!--    size="35%"-->
+  <!--  >-->
+  <!--    <QuestionUpdater :question="questionVO" @closeDialog="closeDialog"/>-->
+  <!--  </el-drawer>-->
 
 </template>
 
@@ -216,7 +216,7 @@ export default {
       }
     },
     updateQuestion() {
-      this.dialog = true;
+      this.$emit("update");
     },
     handleClose() {
       this.$confirm('此操作将丢失填写信息, 是否继续?', '提示', {
@@ -243,21 +243,21 @@ export default {
           operationType: "Delete",
         }
         this.$api.updateQuestion(this.questionVO)
-          .then(res => {
-            this.$message({
-              type: 'success',
-              message: '删除成功!'
-            });
-            this.isDelete = true;
-            record.questionId = res.data.result.id;
-            record.time = new Date();
-            this.$api.createRecord(record)
-              .then(res1 => {
-                console.log(res1);
-              }).catch(err1 => {
-              console.log(err1);
-            })
-          }).catch(error => {
+            .then(res => {
+              this.$message({
+                type: 'success',
+                message: '删除成功!'
+              });
+              this.isDelete = true;
+              record.questionId = res.data.result.id;
+              record.time = new Date();
+              this.$api.createRecord(record)
+                  .then(res1 => {
+                    console.log(res1);
+                  }).catch(err1 => {
+                console.log(err1);
+              })
+            }).catch(error => {
           console.log(error);
           this.$notify.error({
             title: '错误',
@@ -302,35 +302,36 @@ export default {
   mounted() {
     if (this.questionVO.checkedUserId) {
       this.$api.getUserById(this.questionVO.checkedUserId) // 异步函数1:根据用户ID获得用户名称
-        .then(res => {
-          if (res.data.result.name) {
-            this.checkedUserName = res.data.result.name;
-          }
-        }).catch(err => {
+          .then(res => {
+            if (res.data.result.name) {
+              this.checkedUserName = res.data.result.name;
+            }
+          }).catch(err => {
         console.log(err);
       })
     }
 
     this.$api.getRecordByQid(this.questionVO.id) // 异步函数2:根据题目id获得ope_record
-      .then(res1 => {
-        let tempList = res1.data.result.content;
-        this.recordList = tempList;
-        for (let record of tempList) { //这里换成this.recordList是没问题的
-          if (!this.recordNameDict[record.userId]) {
-            this.$api.getUserById(record.userId) //异步函数3:根据记录中的用户ID获得其name
-              .then(res2 => {
-                if (res2.data.result.name) {
-                  this.recordNameDict[record.userId] = res2.data.result.name;
-                }
-              }).catch(err2 => {
-              console.log(err2);
-            })
+        .then(res1 => {
+          let tempList = res1.data.result.content;
+          this.recordList = tempList;
+          for (let record of tempList) { //这里换成this.recordList是没问题的
+            if (!this.recordNameDict[record.userId]) {
+              this.$api.getUserById(record.userId) //异步函数3:根据记录中的用户ID获得其name
+                  .then(res2 => {
+                    if (res2.data.result.name) {
+                      this.recordNameDict[record.userId] = res2.data.result.name;
+                    }
+                  }).catch(err2 => {
+                console.log(err2);
+              })
+            }
           }
-        }
-      }).catch(err1 => {
+        }).catch(err1 => {
       console.log(err1);
     });
-  }
+  },
+  emits: ["update"],
 }
 </script>
 

+ 100 - 14
src/components/QuestionCreator/SingleQuestionCreator.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div style="text-align: left">
     <el-form ref="form" :model="form" label-width="120px">
       <el-form-item label="题干">
         <el-input v-model="form.stem" placeholder="请输入题干内容"></el-input>
@@ -69,8 +69,10 @@
         <el-input v-model="form.keyPoints" placeholder="请输入题目关键词"></el-input>
       </el-form-item>
     </el-form>
-    <el-button type="primary" @click="handleAckButtonClick">确定</el-button>
-    <el-button type="danger">取消</el-button>
+    <div style="text-align: center">
+      <el-button type="primary" @click="handleAckButtonClick">确定</el-button>
+      <el-button type="danger">取消</el-button>
+    </div>
   </div>
 </template>
 
@@ -80,9 +82,17 @@ import {knowledgeData} from "@/utils/knowledgeData";
 export default {
   name: "SingleQuestionCreator",
   components: {},
+  props: {
+    target: {
+      type: String,
+      default: "create",
+    },
+  },
   data() {
     return {
+      old_question: String,
       form: {
+        id: null,
         stem: "",
         type: 1,
         options: [
@@ -129,15 +139,39 @@ export default {
     async handleAckButtonClick() {
       if (this.checkFormCompletion()) {
         let questionVO = this.formatQuestionVO2backend();
-        let res = await this.$api.createQuestion(questionVO);
-        if (res.status === 200) {
-          this.$message({
-            message: '新建题目成功!',
-            type: 'success'
-          });
+        let res;
+        switch (this.target) {
+          case "create":
+            res = await this.$api.createQuestion(questionVO);
+            if (res.status === 200) {
+              this.$message({
+                message: '新建题目成功!',
+                type: 'success'
+              });
+            }
+            break;
+          case "update":
+            let old_question = JSON.parse(this.old_question);
+            old_question.state = "UPDATING"
+            questionVO.state = null;
+            delete questionVO.id;
+            delete questionVO.createdTime;
+            // todo 还没验证过
+             let create_res = await this.$api.createQuestion(questionVO);
+             if(create_res.data.code === "00000"){
+               old_question.remark = create_res.data.result.id;
+             }
+            res = await this.$api.updateQuestion(old_question);
+            if (res.status === 200) {
+              this.$message({
+                message: '更新题目成功!',
+                type: 'success'
+              });
+            }
+            break;
         }
-
       }
+      this.$emit("acknowledge");
     },
 
     checkFormCompletion() {
@@ -240,6 +274,7 @@ export default {
 
     initSingleQuestionCreator() {
       this.form = {
+        id: null,
         stem: "",
         type: 1,
         options: [
@@ -269,7 +304,7 @@ export default {
     formatQuestionVO2backend() {
       const savedUserId = this.$store.state.user.id;
       const checkedUserId = this.$store.state.user.id;
-      const createTime = new Date();
+      const createdTime = new Date();
       const lastModifiedTime = new Date();
       const state = "CHECKING";
 
@@ -306,17 +341,18 @@ export default {
       let tags = [this.form.tags];
 
       return {
+        id: this.form.id,
         stem: this.form.stem,
         type,
         options,
         answer: (this.form.type !== 2) ? this.form.answer : multi_answer,
         analysis: this.form.analysis,
-        difficulty: this.form.difficulty,
+        weight: this.form.difficulty,
         knowledgeId,
         tags,
         keyPoints: this.form.keyPoints,
         savedUserId,
-        createTime,
+        createdTime,
         lastModifiedTime,
         state
       };
@@ -330,8 +366,58 @@ export default {
         }
       }
     },
+
+    setForm(questionVO) {
+      this.old_question = JSON.stringify(questionVO);
+      let type;
+      switch (questionVO.type) {
+        case "choice":
+          type = 1;
+          break;
+        case "multiple_choice":
+          type = 2;
+          break;
+        case "blank":
+          type = 3;
+          break;
+        case "short_answer":
+          type = 4;
+          break;
+        case "code":
+          type = 5;
+          break;
+      }
+      let options = [];
+      for (let optionsKey in questionVO.options) {
+        options.push({
+          label: optionsKey,
+          content: questionVO.options[optionsKey],
+        })
+      }
+      let multi_answer = [];
+      if (type === 2) {
+        for (let i = 0; i < questionVO.answer.length; i++) {
+          multi_answer.push(questionVO.answer[i]);
+        }
+      }
+
+      this.form = {
+        id: questionVO.id,
+        stem: questionVO.stem,
+        type,
+        options,
+        answer: questionVO.answer,
+        multi_answer,
+        analysis: questionVO.analysis,
+        difficulty: questionVO.weight,
+        knowledgeId: questionVO.knowledgeId,
+        tags: questionVO.tags[0],
+        keyPoints: questionVO.keyPoints,
+      }
+    },
   },
   computed: {},
+  emits: ["acknowledge"],
 }
 </script>
 
@@ -348,4 +434,4 @@ export default {
 :deep(.el-cascader) {
   width: 100%;
 }
-</style>
+</style>

+ 2 - 4
src/components/QuestionUpdater.vue

@@ -212,7 +212,7 @@
                 this.$emit('closeDialog');
             },
             updateQuestion(){
-              const old_question = JSON.parse(this.old_question);
+              let old_question = JSON.parse(this.old_question);
               // console.log("old_question", old_question);
               // console.log("question", this.question);
               this.question.state = null;
@@ -234,7 +234,7 @@
                       type: 'success'
                     });
 
-                    console.log(res.data.result);
+                    console.log("更新返回", res.data.result);
                     record.questionId = res.data.result.id;
                     record.time = new Date();
                     // 如果题目更新成功,那么添加操作记录
@@ -259,8 +259,6 @@
                   console.log(err2);
                 })
 
-
-
             }
         },
       mounted() {

+ 31 - 18
src/router/index.js

@@ -1,23 +1,10 @@
 import {createRouter, createWebHistory} from 'vue-router'
-import Home from '../views/Home.vue'
 import store from '../store/index'
 import {jumpToLogin} from "../api/axios.config";
 import {getUserInfo} from "../api/user";
+import {ElMessageBox} from "element-plus";
 
 const routes = [
-  {
-    path: '/home',
-    name: 'Home',
-    component: Home
-  },
-  {
-    path: '/about',
-    name: 'About',
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
-  },
   {
     path: '/',
     name: 'BokFrontEnd',
@@ -79,6 +66,11 @@ const routes = [
         name: "Paper",
         component: ()=>import("@/views/Bok/Main/Paper")
       },
+      {
+        path: "error",
+        name: "Error",
+        component: ()=>import("@/views/NoPermission")
+      }
     ]
   },
 ]
@@ -89,20 +81,41 @@ const router = createRouter({
 })
 
 router.beforeEach((to, from , next) =>{
+  if(to.path === '/error'){
+    next()
+  }
   const {id_token} = to.query;
   if(id_token){
     store.commit('setToken', id_token);
     getUserInfo().then(({ data }) => {
       store.commit('setUser', data.result)
-      next()
+      if(to.path === '/check' && !store.getters.hasPermission){
+        next('/error')
+      }else{
+        next(to.path)
+      }
     }).catch(err => {
-      console.log(err);
+      console.log(err)
+      store.commit('setToken', null);
+      ElMessageBox.confirm('无权限','登录失败',{
+          confirmButtonText: '重新登陆',
+          cancelButtonText: '返回门户',
+          type: 'error',
+      }).then(()=>{
+        jumpToLogin();
+      }).catch(()=>{
+        window.location.href = 'https://p.seec.seecoder.cn'
+      })
     })
   }else{
     if(!store.getters.isLogin){
-      jumpToLogin();
+      jumpToLogin()
     }else{
-      next();
+      if(to.path === '/check' && !store.getters.hasPermission){
+        next('/error')
+      }else{
+        next()
+      }
     }
   }
 })

+ 31 - 3
src/store/index.js

@@ -1,5 +1,7 @@
 import { createStore } from 'vuex'
 import bok from '@/store/bok'
+import {getUserInfo} from "../api/user";
+import {jumpToLogin} from "../api/axios.config";
 
 export default createStore({
   state: {
@@ -13,9 +15,18 @@ export default createStore({
     },
     setToken(state, token){
       state.token = token;
+      localStorage.setItem('token', token);
     },
     setUser(state, user){
       state.user = user;
+      localStorage.setItem('user', user);
+    },
+    logout(state){
+      state.token = null;
+      localStorage.removeItem('token');
+      state.user = null;
+      localStorage.removeItem('user');
+      jumpToLogin();
     }
   },
   actions: {
@@ -27,10 +38,27 @@ export default createStore({
   },
   getters: {
     showCount: state => {
-      return '苏的state:'+state.myCount;
+      return 'state:'+state.myCount;
     },
-    isLogin: state => Boolean(state.token),
-
+    isLogin: state => {
+      if(state.token){
+        return true;
+      }else if(localStorage.getItem('token')){
+        state.token = localStorage.getItem('token');
+        getUserInfo().then(({ data }) => {
+          state.user = data.result;
+        }).catch(err => {
+          console.log(err);
+          jumpToLogin();
+        })
+        return true;
+      }else{
+        return false;
+      }
+    },
+    hasPermission: state => {
+      return state.user.role === 'ADMIN' || state.user.role === 'SEEC' || state.user.role === 'SEECX';
+    }
   },
   modules: {
     bok

+ 0 - 5
src/views/About.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>

+ 2 - 1
src/views/Bok/Main/Check.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <h1>题目审查</h1>
+    <h1>题目审核</h1>
     <el-tabs v-model="activeName" @tab-click="handleClick">
       <el-tab-pane label="全部审核" name="checkingAll">
         <el-pagination
@@ -268,6 +268,7 @@ export default {
               .then(async res => {
                 console.log("getStateQuestion-UPDATING");
                 const update_list = res.data.result.content;
+                console.log("update_list", update_list);
                 let updating_num = 0;
                 // console.log(update_list)
                 for (const updateListElement of update_list) {

+ 1 - 2
src/views/Bok/Main/Knowledge.vue

@@ -1,7 +1,6 @@
 <template>
   <el-space :fill="true" direction="vertical" class="knowledge-wrapper">
-    <h1>Knowledge</h1>
-
+    <h1>知识点</h1>
     <div class="tree_body">
       <el-input
               class="tree_input"

+ 2 - 4
src/views/Bok/Main/Operation.vue

@@ -1,8 +1,8 @@
 <template>
-  <h1>This is Operation Page!</h1>
+  <h1>新建题目</h1>
   <el-tabs v-model="activeName" @tab-click="handleClick" stretch>
     <el-tab-pane label="新建题目" name="create">
-      <div>新建题目</div>
+<!--      <div>新建题目</div>-->
       <single-question-creator id="single-question-creator"/>
     </el-tab-pane>
     <el-tab-pane label="批量新建题目" name="groupCreate">
@@ -35,8 +35,6 @@
 </template>
 
 <script>
-import {reactive} from "vue";
-import {useApi} from "@/api";
 import SingleQuestionCreator from "@/components/QuestionCreator/SingleQuestionCreator";
 
 export default {

+ 164 - 108
src/views/Bok/Main/QuestionRepository.vue

@@ -1,155 +1,210 @@
 <template>
-  <h1>Question Repository</h1>
-
-  <div>
-    <el-button>新建题目</el-button>
-    <el-button @click="createQuestion">新建题目组</el-button>
-  </div>
-
-  <el-divider/>
-
-  <div>
-    <el-pagination @size-change="handleSizeChange"
-                   @current-change="handleCurrentChange"
-                   :current-page="currentPage"
-                   :page-sizes="[5, 10, 15, 20]"
-                   :page-size="pageSize"
-                   layout="total, sizes, prev, pager, next, jumper"
-                   :total=this.totalNum
-                   v-if="this.questionList.length !== 0"
-    />
-    <primary-question-card v-for="(item,index) in questionList"
-                           :key="item.id"
-                           :question-v-o="item"
-                           :total-num="totalNum"
-                           :cur-num="index+(currentPage-1)*pageSize"/>
-
-    <el-backtop :bottom="50">
-      <div style="height: 100%;width: 100%;background-color: #f2f5f6;box-shadow: 0 0 6px rgba(0,0,0, .12);line-height: 40px;">
-        UP
+    <h1>题库</h1>
+  <el-tabs v-model="tabActiveName" @tab-click="handleTabClick" stretch>
+    <!--APPROVED-->
+    <el-tab-pane label="APPROVED" name="APPROVED">
+<!--      <div>-->
+<!--        <el-button>新建题目</el-button>-->
+<!--        <el-button @click="createQuestion">新建题目组</el-button>-->
+<!--      </div>-->
+<!--      <el-divider/>-->
+      <div>
+        <el-pagination @size-change="handleSizeChange"
+                       @current-change="handleCurrentChange"
+                       :current-page="currentPage"
+                       :page-sizes="[5, 10, 15, 20]"
+                       :page-size="pageSize"
+                       layout="total, sizes, prev, pager, next, jumper"
+                       :total=this.totalNum
+                       v-if="this.questionList.length !== 0"
+        />
+        <primary-question-card v-for="(item,index) in questionList"
+                               :key="item.id"
+                               :question-v-o="item"
+                               :total-num="totalNum"
+                               :cur-num="index+(currentPage-1)*pageSize"
+                               @update="handleQuestionUpdate(item)"/>
+        <el-backtop :bottom="50">
+          <div
+              style="height: 100%;width: 100%;background-color: #f2f5f6;box-shadow: 0 0 6px rgba(0,0,0, .12);line-height: 40px;">
+            UP
+          </div>
+        </el-backtop>
       </div>
-    </el-backtop>
-  </div>
-
-  <el-drawer
-    title="新建题目"
-    :before-close="handleClose"
-    v-model="dialog"
-    direction="rtl"
-    custom-class="question-drawer"
-    ref="drawer"
-    size="35%"
-  >
-    <QuestionCreater :dialog="dialog" @closeDialog="closeDialog"/>
-  </el-drawer>
-
+    </el-tab-pane>
+    <!--REFUSED-->
+    <el-tab-pane label="REFUSED" name="REFUSED">
+      <div>
+        <el-pagination @size-change="handleSizeChange"
+                       @current-change="handleRefusedCurrentChange"
+                       :current-page="refusedCurrentPage"
+                       :page-sizes="[5, 10, 15, 20]"
+                       :page-size="pageSize"
+                       layout="total, sizes, prev, pager, next, jumper"
+                       :total=this.refusedTotalNum
+                       v-if="this.refusedQuestionList.length !== 0"
+        />
+        <primary-question-card v-for="(item,index) in refusedQuestionList"
+                               :key="item.id"
+                               :question-v-o="item"
+                               :total-num="refusedTotalNum"
+                               :cur-num="index+(refusedCurrentPage-1)*pageSize"
+                               @update="handleQuestionUpdate(item)"/>
+        <el-backtop :bottom="50">
+          <div
+              style="height: 100%;width: 100%;background-color: #f2f5f6;box-shadow: 0 0 6px rgba(0,0,0, .12);line-height: 40px;">
+            UP
+          </div>
+        </el-backtop>
+      </div>
+    </el-tab-pane>
+  </el-tabs>
+  <!--修改框-->
   <el-drawer
-    title="批量新建题目"
-    :before-close="handleClose"
-    v-model="dialog1"
-    direction="rtl"
-    custom-class="questionGroup-drawer"
-    ref="drawer"
-    size="35%"
-  >
-    <QuestionGroupCreater :dialog="dialog1" @closeDialog="closeDialog1"/>
+      title="更新题目"
+      :before-close="handleClose"
+      v-model="dialog"
+      direction="rtl"
+      custom-class="question-drawer"
+      ref="drawer"
+      size="35%">
+    <single-question-creator ref="QuestionUpdater"
+                             @acknowledge="handleQuestionCreatorAcknowledge"
+                             :target="creatorTarget"/>
   </el-drawer>
 </template>
 
 <script>
-import QuestionGroupCreater from "../../../components/QuestionGroupCreater.vue";
-import QuestionCreater from "@/components/QuestionCreater";
-import BriefQuestionCard from "../../../components/BriefQuestionCard.vue";
 import PrimaryQuestionCard from "@/components/QuestionCard/PrimaryQuestionCard";
+import SingleQuestionCreator from "@/components/QuestionCreator/SingleQuestionCreator";
 
 export default {
   name: "QuestionRepository",
   components: {
-    QuestionGroupCreater,
-    BriefQuestionCard,
+    SingleQuestionCreator,
     PrimaryQuestionCard,
-    QuestionCreater
   },
   data() {
     return {
-      info: null,
+      dialog: true,
+      pageSize: 20,
+
       questionList: [],
-      dialog: false,
-      dialog1: false,
       currentPage: 1,
-      pageSize: 20,
       totalNum: 0,
+
+      refusedQuestionList: [],
+      refusedCurrentPage: 1,
+      refusedTotalNum: 0,
+
+      tabActiveName: "APPROVED",
+
+      creatorTarget: "update",
     }
   },
   mounted() {
-    // console.log(this.questionList)
-
+    this.dialog = false;
     // 挂载时获取第一页题目列表
     let states = 'APPROVED';
     this.$api.getStateQuestion(states, 0, this.pageSize)
-      .then(res => {
-        // console.log("QuestionRepository/index");
-        // console.log(res);
-        this.questionList = res.data.result.content;
-        this.totalNum = res.data.result.totalElements;
-      }).catch(error => {
-      // console.log(error);
-    })
+        .then(res => {
+          console.log(res);
+          this.questionList = res.data.result.content;
+          this.totalNum = res.data.result.totalElements;
+        })
+        .catch(error => {
+          console.log(error);
+        })
   },
   computed: {},
   methods: {
-    createQuestion() {
-      this.dialog = true;
-    },
-
-    createQuestionByGruop() {
-      this.dialog1 = true;
-    },
+    // createQuestion() {
+    //   this.dialog = true;
+    // },
 
     handleClose(done) {
-      // if (this.loading) {
-      //   return;
-      // }
-      // this.$confirm('确定要提交表单吗?')
-      //   .then(_ => {
-      //     this.loading = true;
-          // this.timer = setTimeout(() => {
-          //   done();
-          //   // 动画关闭需要一定的时间
-          //   setTimeout(() => {
-          //     this.loading = false;
-          //   }, 400);
-          // }, 2000);
-        // })
-        // .catch(_ => {
-        // });
+      this.$confirm('确认关闭?')
+          .then(_ => {
+            done();
+          })
+          .catch(_ => {
+          });
     },
 
     closeDialog() {
       this.dialog = false;
     },
 
-    closeDialog1() {
-      this.dialog1 = false;
-    },
-
     handleSizeChange(val) {
       // console.log(`QuestionRepository/index-handleSizeChange 每页 ${val} 条`);
       this.pageSize = val;
     },
 
     handleCurrentChange(val) { // 当点击新的页面时才请求新的数据
-      // console.log(`QuestionRepository/index-handleCurrentChange 当前页: ${val}`);
       this.currentPage = val;
       let states = 'APPROVED';
       this.$api.getStateQuestion(states, val - 1, this.pageSize)
-        .then(res => {
-          // console.log("handleCurrentChange-result");
-          // console.log(res);
-          this.questionList = res.data.result.content;
-        }).catch(error => {
-        // console.log(error);
-      })
+          .then(res => {
+            console.log(res);
+            this.questionList = res.data.result.content;
+          })
+          .catch(error => {
+            console.log(error);
+          })
+    },
+
+    handleRefusedCurrentChange(val) { // 当点击新的页面时才请求新的数据
+      this.currentPage = val;
+      let states = 'REFUSED';
+      this.$api.getStateQuestion(states, val - 1, this.pageSize)
+          .then(res => {
+            console.log(res);
+            this.questionList = res.data.result.content;
+          })
+          .catch(error => {
+            console.log(error);
+          })
+    },
+
+    handleTabClick(tabItem) {
+      let state = tabItem.props.label;
+      switch (state) {
+        case "APPROVED":
+          this.$api.getStateQuestion(state, 0, this.pageSize)
+              .then(res => {
+                console.log(res);
+                this.questionList = res.data.result.content;
+                this.totalNum = res.data.result.totalElements;
+                this.currentPage = 1;
+              })
+              .catch(error => {
+                console.log(error);
+              });
+          break;
+        case "REFUSED":
+          this.$api.getStateQuestion(state, 0, this.pageSize)
+              .then(res => {
+                console.log(res);
+                this.refusedQuestionList = res.data.result.content;
+                this.refusedTotalNum = res.data.result.totalElements;
+                this.refusedCurrentPage = 1;
+              })
+              .catch(error => {
+                console.log(error);
+              })
+          break;
+        default:
+          break;
+      }
+    },
+
+    handleQuestionUpdate(item) {
+      this.dialog = true;
+      this.$refs.QuestionUpdater.setForm(item);
+    },
+
+    handleQuestionCreatorAcknowledge() {
+      this.dialog = false;
     },
   },
 }
@@ -162,9 +217,10 @@ export default {
 
 .el-drawer {
   overflow-y: auto;
+  padding: 0 20px;
 }
 
-.el-dialog{
+.el-dialog {
   margin: auto auto 15vh;
 }
 </style>

+ 1 - 1
src/views/Bok/Main/Search/index.vue

@@ -1,6 +1,6 @@
 <template>
     <el-space :fill="true" direction="vertical" alignment="flex-start" :size="30" style="width: 90%;">
-        <h1>Question Search</h1>
+        <h1>题目搜索</h1>
         <el-input placeholder="请输入内容" v-model="searchContent" @keydown.enter="clickSearch">
             <template #append>
                 <el-button icon="el-icon-search" @click="clickSearch"></el-button>

+ 89 - 69
src/views/Bok/NavBar.vue

@@ -1,65 +1,71 @@
 <template>
-    <div class="navbar-wrapper">
-        <el-input placeholder="请输入内容" v-model="searchContent" size="mini" class="input-with-select"
-        v-if="$route.path!=='/search'" @keydown.enter="clickSearch">
-            <template #append>
-                <el-button icon="el-icon-search" @click="clickSearch"/>
-            </template>
-        </el-input>
-        <el-dropdown trigger="click" style="position: absolute;top: 0px;right: 0px">
-          <p style="position: absolute;top: 15px;left: -80px">{{$store.state.user.name}}</p>
-            <el-avatar shape="square" :size="30" :src="squareUrl"></el-avatar>
-            <template #dropdown>
-                <el-dropdown-menu>
-                    <el-dropdown-item>{{$store.state.user.name}}</el-dropdown-item>
-                    <el-dropdown-item>选项2</el-dropdown-item>
-                    <el-dropdown-item>选项3</el-dropdown-item>
-                    <el-dropdown-item>选项4</el-dropdown-item>
-                </el-dropdown-menu>
-            </template>
-        </el-dropdown>
-    </div>
+  <div class="navbar-wrapper">
+    <el-input placeholder="请输入内容" v-model="searchContent" size="mini" class="input-with-select"
+              v-if="$route.path!=='/search'" @keydown.enter="clickSearch">
+      <template #append>
+        <el-button icon="el-icon-search" @click="clickSearch"/>
+      </template>
+    </el-input>
+    <el-dropdown trigger="click" style="position: absolute;top: 0px;right: 0px">
+      <div class="user-wrap">
+        <span class="user-name">{{ $store.state.user.name }}</span>
+        <el-avatar shape="square" :size="30" :src="squareUrl"></el-avatar>
+      </div>
+      <template #dropdown>
+        <el-dropdown-menu>
+<!--          <el-dropdown-item>{{ $store.state.user.name }}</el-dropdown-item>-->
+          <el-dropdown-item @click="logout">
+            <i class="el-icon-switch-button"></i>
+            登出
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </template>
+    </el-dropdown>
+  </div>
 </template>
 
 <script>
 export default {
-    name: "NavBar",
-    data() {
-        return {
-            //
-            searchContent: "",
+  name: "NavBar",
+  data() {
+    return {
+      //
+      searchContent: "",
 
-            systemName: "bok",
-            squareUrl: "https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png",
-        }
-    },
-    computed: {
-        path() {
-            const _this = this
-            let res = _this.$store.getters['bok/getPath'].split("/")
-            res[0] = _this.systemName
-            return res
-        }
-    },
-    mounted() {
-    },
-    methods: {
-        //
-        clickSearch(){
-            const _this = this
-            let content = _this.searchContent
-            _this.searchContent = ""
-            if(content!==""){
-                this.$router.replace({
-                    name: "Search",
-                    path:'/Search',
-                    params:{
-                        searchContent:content,
-                    }
-                })
-            }
-        },
+      systemName: "bok",
+      squareUrl: "https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png",
+    }
+  },
+  computed: {
+    path() {
+      const _this = this
+      let res = _this.$store.getters['bok/getPath'].split("/")
+      res[0] = _this.systemName
+      return res
+    }
+  },
+  mounted() {
+  },
+  methods: {
+    //
+    clickSearch() {
+      const _this = this
+      let content = _this.searchContent
+      _this.searchContent = ""
+      if (content !== "") {
+        this.$router.replace({
+          name: "Search",
+          path: '/Search',
+          params: {
+            searchContent: content,
+          }
+        })
+      }
     },
+    logout() {
+      this.$store.commit('logout');
+    }
+  },
 }
 </script>
 
@@ -67,34 +73,48 @@ export default {
 @import "../../style/variables";
 
 .navbar-wrapper {
-    height: 50px;
-    box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
-    position: relative;
+  height: 50px;
+  box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+  position: relative;
 }
 
 .el-breadcrumb {
-    height: calc(100% - 30px);
-    padding: 15px;
-    font-size: 20px;
+  height: calc(100% - 30px);
+  padding: 15px;
+  font-size: 20px;
+}
+
+.user-wrap{
+  display: flex;
+  cursor: pointer;
+
+  .user-name{
+    margin-right: 16px;
+    padding-top: 18px;
+  }
+}
+
+.el-dropdown:hover{
+  cursor: pointer;
 }
 
 .el-avatar {
-    margin: 10px;
+  margin: 10px;
 }
 
 .el-avatar:hover {
-    cursor: pointer;
+  cursor: pointer;
 }
 
 .el-input {
-    position: absolute;
-    top: 11px;
-    left: 25%;
-    //height: 50%;
-    width: 50%;
+  position: absolute;
+  top: 11px;
+  left: 25%;
+  //height: 50%;
+  width: 50%;
 }
 
 .input-with-select .el-input-group__prepend {
-    background-color: #fff;
+  background-color: #fff;
 }
 </style>

+ 6 - 4
src/views/Bok/SideBar.vue

@@ -25,11 +25,11 @@
         <i class="el-icon-menu"></i>
         <template #title>知识点</template>
       </el-menu-item>
-      <el-menu-item index="knowledgeGraph">
+      <el-menu-item index="knowledgeGraph"  v-if="false">
         <i class="el-icon-connection"></i>
         <template #title>知识图谱</template>
       </el-menu-item>
-      <el-menu-item index="paper">
+      <el-menu-item index="paper"  v-if="false">
         <i class="el-icon-document"></i>
         <template #title>试卷袋</template>
       </el-menu-item>
@@ -37,7 +37,7 @@
         <i class="el-icon-circle-check"></i>
         <template #title>审核</template>
       </el-menu-item>
-      <el-menu-item index="setting">
+      <el-menu-item index="setting" v-if="false">
         <i class="el-icon-setting"></i>
         <template #title>设置</template>
       </el-menu-item>
@@ -54,7 +54,9 @@ export default {
       return this.$route.path.split("/")[1]
     },
     role(){ //获得当前登录用户的角色;审查界面只给ADMIN用户显示。
-      return this.$store.state.user.role === 'ADMIN';
+      return this.$store.state.user.role === 'ADMIN'
+          ||this.$store.state.user.role === 'SEEC'||this.$store.state.user.role === 'SEECX';
+      // return true;
     }
   },
   methods: {

+ 0 - 18
src/views/Home.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="home">
-    <img alt="Vue logo" src="../assets/logo.png">
-    <HelloWorld msg="Welcome to Your Vue.js App"/>
-  </div>
-</template>
-
-<script>
-// @ is an alias to /src
-import HelloWorld from '@/components/HelloWorld.vue'
-
-export default {
-  name: 'Home',
-  components: {
-    HelloWorld
-  }
-}
-</script>

+ 26 - 0
src/views/NoPermission.vue

@@ -0,0 +1,26 @@
+<template>
+  <div>
+    <h1>权限不足</h1>
+    <a class="link" @click="back">返回上一页</a>
+    <a class="link" href="https://p.seec.seecoder.cn">返回门户</a>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "NoPermission",
+  methods: {
+    back() {
+      window.history.go(-1);
+    }
+  }
+}
+</script>
+
+<style scoped>
+.link{
+  color: blue;
+  text-decoration: underline;
+  margin: 20px;
+}
+</style>

+ 0 - 13
tests/unit/example.spec.js

@@ -1,13 +0,0 @@
-import { expect } from 'chai'
-import { shallowMount } from '@vue/test-utils'
-import HelloWorld from '@/components/HelloWorld.vue'
-
-describe('HelloWorld.vue', () => {
-  it('renders props.msg when passed', () => {
-    const msg = 'new message'
-    const wrapper = shallowMount(HelloWorld, {
-      props: { msg }
-    })
-    expect(wrapper.text()).to.include(msg)
-  })
-})