Browse Source

Leone update QuestionCard

Leonezhurui 5 years ago
parent
commit
d5362e0529

+ 3 - 0
src/api/prefix.js

@@ -0,0 +1,3 @@
+const BASE_URL = '/api'
+
+export const QUESTION_MODULE = BASE_URL + '/question'

+ 26 - 0
src/api/question.js

@@ -0,0 +1,26 @@
+import axios from 'axios'
+import {QUESTION_MODULE} from "./prefix";
+
+export const test = () => {
+    return "Test Successfully!";
+}
+
+export const getTargetQuestionList = (offset, pageSize) => {
+    return axios.get("/api/api/pageQuestion", {
+        params:{
+            offset: offset,
+            pageSize: pageSize
+        }});
+}
+
+export const deleteQuestionById = (id) => {
+    return axios.delete("api/api/question/"+id);
+}
+
+export const createQuestion = (questionvo) => {
+    return axios.post("")
+}
+
+export const updateQuestion = (questionvo) => {
+    return axios.put("api/api/question/"+questionvo.id, questionvo);
+}

+ 1 - 1
src/components/MarkdownText.vue

@@ -41,7 +41,7 @@
         /*white-space: pre-wrap;*/
         /*margin-top: 16px;*/
         p {
-            /*margin-bottom: 0;*/
+            margin-bottom: 0;
         }
         img {
             max-width: 100%;

+ 318 - 0
src/components/QuestionItem/AbstractQuestionCard.vue

@@ -0,0 +1,318 @@
+<template>
+    <el-card class="bQuestion-card" shadow="hover">
+        <template #header>
+            <el-row>
+                <el-col :span="3">
+                    <span><strong>S/N: </strong>{{curNum+1}} / {{totalNum}}</span>
+                </el-col>
+
+                <el-col :span="5">
+                    <span><strong>题目类型: </strong>{{questionvo.type}}</span>
+                </el-col>
+
+                <el-col :span="6">
+                    <div class="bQuestion-card-body-knowledgeID">
+                            <span v-if="questionvo.knowledgeId && questionvo.knowledgeId.length !== 0">
+                                <span><strong>KnowledgeId: </strong></span>
+                                <el-tooltip v-for="item in questionvo.knowledgeId" effect="dark" placement="bottom">
+                                    <template #content>
+                                        {{map1(item)}}
+                                    </template>
+                                    <el-tag  effect="dark" style="margin-right: 2px">{{item}}</el-tag>
+                                </el-tooltip>
+                            </span>
+                        <span v-else>
+                                <span><strong>KnowledgeId: </strong>null</span>
+                            </span>
+                    </div>
+                </el-col>
+
+                <el-col :span="6"/>
+                <el-col :span="2">
+                    <el-button type="text" circle @click="expand" v-if="!isAll"><strong>查看全部</strong></el-button>
+                    <el-button type="text" circle @click="withdraw" v-if="isAll"><strong>收起</strong></el-button>
+                </el-col>
+                <el-col :span="1">
+                    <el-button type="primary" icon="el-icon-edit" circle @click="updateQuestion"></el-button>
+                </el-col>
+                <el-col :span="1">
+                    <el-button v-if="isDelete === false" type="danger" icon="el-icon-delete" circle @click="deleteQuestion"></el-button>
+                    <el-button v-else type="success" icon="el-icon-delete" circle @click="recoverQuestion"></el-button>
+                </el-col>
+            </el-row>
+        </template>
+
+        <div class="bQuestion-card-body">
+            <div class="bQuestion-card-body-stem">
+                <div>
+                    <MarkdownText :raw="'<strong>题目: </strong>'+questionvo.stem"></MarkdownText>
+                </div>
+                <div class="stem-extension" v-if="isAll">
+                    <div class="bQuestion-card-body-options" v-if="questionvo.type === 'choice'">
+                        <div v-for="(item,index) in questionvo.options" >
+                            <div v-if="questionvo.answer.split('').indexOf(index) !== -1" class="underline-correct-answer">
+                                <MarkdownText :raw="index+': '+item"></MarkdownText>
+                            </div>
+                            <div v-else>
+                                <MarkdownText :raw="index+': '+item"></MarkdownText>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="bQuestion-card-body-options" v-if="questionvo.type === 'multiple_choice'">
+                        <div v-for="(item,index) in questionvo.options" >
+                            <div v-if="questionvo.answer.split(';').indexOf(index) !== -1" class="underline-correct-answer">
+                                <MarkdownText :raw="index+': '+item"></MarkdownText>
+                            </div>
+                            <div v-else>
+                                <MarkdownText :raw="index+': '+item"></MarkdownText>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="bQuestion-card-body-blanks" v-if="questionvo.type === 'blank'">
+                        <div v-for="index in Object.keys(questionvo.blanks).length">
+                            <div class="correct_answer">
+                                __{{index}}__: {{questionvo.blanks['__'+index+'__']}}
+                            </div>
+                        </div>
+                    </div>
+                    <div class="bQuestion-card-body-true_false" v-if="questionvo.type === 'true_false'">
+                        <div class="correct_answer"> {{questionvo.answer}}</div>
+                    </div>
+                </div>
+            </div>
+
+            <el-divider v-if="isAll"></el-divider>
+
+            <div class="bQuestion-card-body-info" v-if="isAll">
+                <div class="info-block">
+                    <el-row>
+                        <el-col :span="10">
+                            <strong>KeyPoints: </strong>{{questionvo.keyPoints}}
+                        </el-col>
+                        <el-col :span="6">
+                            <strong>题目难度: </strong>{{questionvo.weight}}/5
+                        </el-col>
+                        <el-col :span="4">
+                                <span><strong>Tags: </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>
+                                <span v-else>
+                                    <span>no tags</span>
+                                </span>
+                        </el-col>
+                    </el-row>
+                </div>
+                <div>
+                    <div class="info-block"
+                         v-if="questionvo.type === 'choice' ||
+                         questionvo.type === 'multiple_choice' ||
+                         questionvo.type === 'true_false' ||
+                         questionvo.type === 'short_answer'">
+                        <MarkdownText :raw="'<strong>正确答案: </strong>'+questionvo.answer"></MarkdownText>
+                    </div>
+                </div>
+                <div>
+                    <div class="info-block"
+                         v-if="questionvo.type === 'choice' ||
+                         questionvo.type === 'multiple_choice' ||
+                         questionvo.type === 'true_false'">
+                        <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+                    </div>
+                    <div class="info-block" v-if="questionvo.type === 'blank' && questionvo.analysis.length > 5">
+                        <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+                    </div>
+                    <div class="info-block" v-if="questionvo.type === 'short_answer' && questionvo.analysis.length > 5">
+                        <MarkdownText :raw="'<strong>解析: </strong>'+questionvo.analysis"></MarkdownText>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <el-divider v-if="isAll"></el-divider>
+
+        <div class="bQuestion-card-footer" v-if="isAll">
+            <div>
+                <el-row>
+                    <el-col :span="3">
+                        <div><strong>状态: </strong>已审核</div>
+                    </el-col>
+                    <el-col :span="5">
+                        <div><strong>审核人: </strong>小苏</div>
+                    </el-col>
+
+                    <el-col :span="10"></el-col>
+
+                    <el-col :span="6" v-if="!questionvo.lastModifiedTime">
+                        <div><strong>CreateTime: </strong>{{toMyDate(questionvo.createdTime)}}</div>
+                    </el-col>
+
+                    <el-col :span="6" v-else>
+                        <div><strong>lastModifiedTime: </strong>{{toMyDate(questionvo.lastModifiedTime)}}</div>
+                    </el-col>
+                </el-row>
+            </div>
+        </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>
+</template>
+
+<script>
+    import MarkdownText from "../MarkdownText";
+    import {map} from "../../utils/knowledgeMapper";
+    import {deleteQuestionById} from "../../api/question";
+    import QuestionUpdater from "../card/QuestionUpdater";
+
+    export default {
+        name: "AbstractQuestionCard",
+        components: {
+            MarkdownText,
+            QuestionUpdater
+        },
+        props: {
+            questionvo: Object,
+            curNum: Number,
+            totalNum: Number,
+        },
+        data(){
+            return{
+                isAll: false,
+                isDelete: false,
+                dialog: false,
+            }
+        },
+        methods:{
+            map1(abbreviation){
+                return map(abbreviation)
+            },
+            expand(){
+                if(!this.isAll){
+                    this.isAll = true;
+                }
+            },
+            withdraw(){
+                if(this.isAll){
+                    this.isAll = false;
+                }
+            },
+            updateQuestion(){
+                this.dialog = true;
+            },
+            handleClose(){
+                this.$confirm('此操作将丢失填写信息, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    this.dialog = false;
+                })
+            },
+            closeDialog(){
+                this.dialog = false;
+            },
+            deleteQuestion(){
+                this.$confirm('此操作将永久删除该题目, 是否继续?', '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                }).then(() => {
+                    deleteQuestionById(this.questionvo.id).then(() => {
+                        this.$message({
+                            type: 'success',
+                            message: '删除成功!'
+                        });
+                        this.isDelete = true;
+                    }).catch( error => {
+                        console.log(error);
+                        this.$notify.error({
+                            title: '错误',
+                            message: '删除失败'
+                        });
+                    })
+                }).catch(() => {
+                    this.$message({
+                        type: 'info',
+                        message: '已取消删除'
+                    });
+                });
+            },
+            recoverQuestion(){
+                alert("Delete successfully!");
+            },
+            toMyDate(instant){
+                let date = new Date(instant);
+                let year = date.getFullYear();
+                let month = date.getMonth() + 1;
+                let theDate = date.getDate();
+                let hour = date.getHours();
+                let minute = date.getMinutes();
+                let second = date.getSeconds();
+                if ( month < 10 ) { month = '0' + month; }
+                if ( theDate < 10 ) { theDate = '0' + theDate; }
+                if ( hour < 10 ) { hour = '0' + hour; }
+                if ( minute < 10 ) { minute = '0' + minute; }
+                if ( second < 10 ) { second = '0' + second; }
+                return year +"-"+ month +"-" + theDate + " "+ hour +":"+ minute +":"+ second;
+            }
+        },
+        mounted() {
+        }
+    }
+</script>
+
+<style>
+    .bQuestion-card{
+        margin: 20px;
+        font-size: 18px;
+        background-color: #eef7f2;
+    }
+    .bQuestion-card-body{
+        text-align: left;
+        margin-left: 32px;
+        font-size: 20px;
+        font-family: "Songti SC";
+    }
+
+    p {
+        display: block;
+        margin-block-start: 0px;
+        margin-block-end: 0px;
+        margin-inline-start: 0px;
+        margin-inline-end: 0px;
+    }
+
+    .bQuestion-card-body-options{
+        margin-top: 10px;
+        font-size: 18px;
+    }
+
+    .underline-correct-answer{
+        font-family: "Kaiti SC";
+        font-size: 22px;
+        color: #f1939c;
+        font-weight: bold;
+        text-decoration: underline;
+    }
+    .correct_answer{
+        font-family: "Kaiti SC";
+        font-size: 21px;
+        color: #f1939c;
+        font-weight: bold;
+    }
+
+    .info-block{
+        margin-bottom: 10px;
+    }
+
+</style>

+ 19 - 6
src/components/bok/bokMain/KnowledgeGraph.vue

@@ -1,13 +1,26 @@
 <template>
-<div><h1>Knowledge Graph</h1></div>
+    <div><h1>Knowledge Graph</h1></div>
+
 </template>
 
 <script>
-export default {
-  name: "KnowledgeGraph"
-}
+    export default {
+        name: "KnowledgeGraph",
+        components: {
+        },
+        data(){
+            return{
+            }
+        },
+        methods: {
+
+        },
+        mounted() {
+
+        }
+    }
 </script>
 
-<style scoped>
+<style>
 
-</style>
+</style>

+ 3 - 1
src/components/bok/bokMain/QuestionRepository/index.vue

@@ -24,7 +24,7 @@
     </div>
 
     <div class="QuestionBody">
-      <BriefQuestionCard v-for="(item,index) in questionList"
+      <AbstractQuestionCard v-for="(item,index) in questionList"
                          :key="index"
                          :questionvo="item" :total-num="totalNum" :cur-num="index+(currentPage-1)*pageSize" />
     </div>
@@ -78,6 +78,7 @@
   import QuestionCreater from "../../../card/QuestionCreater.vue";
   import QuestionGroupCreater from "../../../card/QuestionGroupCreater.vue";
   import BriefQuestionCard from "../../../card/BriefQuestionCard.vue";
+  import AbstractQuestionCard from "../../../QuestionItem/AbstractQuestionCard";
 
 export default {
   name: "QuestionRepository",
@@ -85,6 +86,7 @@ export default {
     QuestionCreater,
     QuestionGroupCreater,
     BriefQuestionCard,
+    AbstractQuestionCard
   },
   data() {
     return{

+ 30 - 9
src/components/bok/bokMain/search/index.vue

@@ -26,11 +26,10 @@
                        v-model:current-page="pagination.current" :page-sizes="pagination.sizes"
                        v-model:page-size="pagination.size" :layout="pagination.layout"
                        :total="filteredQuestions.length"/>
-        <el-space :fill="true" direction="vertical">
-            <brief-question-card v-for="(item, index) in currentQuestions" :questionvo="item"
-                                 :total-num="filteredQuestions.length"
-                                 :cur-num="index+pagination.size*(pagination.current-1)"/>
-        </el-space>
+
+        <AbstractQuestionCard v-for="(item, index) in currentQuestions" :questionvo="item"
+                             :total-num="filteredQuestions.length"
+                             :cur-num="index+pagination.size*(pagination.current-1)"/>
     </el-space>
 </template>
 
@@ -40,6 +39,7 @@ import ButtonFilter from "@/components/tool/ButtonFilter";
 import Sorter from "@/components/tool/Sorter";
 import BriefQuestionCard from "@/components/card/BriefQuestionCard";
 import SearchFilter from "@/components/tool/SearchFilter";
+import AbstractQuestionCard from "../../../QuestionItem/AbstractQuestionCard";
 import axios from "axios";
 import src from "./srcData"
 
@@ -50,7 +50,8 @@ export default {
         ButtonFilter,
         SearchFilter,
         "qr-sorter": Sorter,
-        BriefQuestionCard
+        BriefQuestionCard,
+        AbstractQuestionCard
     },
     data() {
         return {
@@ -93,6 +94,8 @@ export default {
                 layout: "total, sizes, prev, pager, next, jumper",
                 sizes: [5, 10, 20]
             },
+            totalNum: 0,
+
         }
     },
     computed: {
@@ -258,6 +261,7 @@ export default {
                 alert("请输入关键词");
             } else {
                 await this.requestQuestion(this.searchContent, [], [], [], [])
+                console.log(_this.resultQuestions);
                 _this.resultQuestions = _this.resultQuestions.map(function (item) {
                     return {
                         type: true,
@@ -296,17 +300,20 @@ export default {
 
         // todo 注释 添加到api文件当中
         async requestQuestion(stem, ...items) {
-            await axios.get("/api/api/question", {
+            await axios.get("/api/api/searchQuestion", {
                 params: {
                     stem: stem,
                     tags: items[0],
                     type: items[1],
                     weights: items[2],
-                    knowledgeId: items[3]
+                    knowledgeId: items[3],
+                    offset: 0,
+                    pageSize: 1000
                 }
             }).then(res => {
                 console.log(res);
-                this.resultQuestions = res.data.questions
+                this.resultQuestions = res.data.content;
+                this.totalNum = res.data.totalElements;
                 this.$notify({
                     title: '成功',
                     message: '搜索成功',
@@ -329,6 +336,20 @@ export default {
 
         //
         handleCurrentChange(val) {
+            // console.log(`当前页: ${val}`);
+            // axios.get("/api/api/pageQuestion", {
+            //     params:{
+            //         offset: val-1,
+            //         pageSize: this.pagination.size
+            //     }})
+            //     .then(res => {
+            //         this.resultQuestions = res.data.content;
+            //     }).catch(error => {
+            //     console.log(error);
+            // }).finally(() => {
+            //     console.log("change page completed");
+            // });
+            // this.currentPage = val;
         },
 
     }

+ 3 - 3
src/components/card/BriefQuestionCard.vue

@@ -58,7 +58,7 @@
                     </div>
                 </div>
                 <div v-for="index in Object.keys(questionvo.blanks).length" v-if="questionvo.type === 'blank'">
-                    <div class="correct-answer">
+                    <div class="correct_answer">
                         __{{index}}__: {{questionvo.blanks['__'+index+'__']}}
                     </div>
                 </div>
@@ -70,7 +70,7 @@
             <el-divider v-if="isAll"></el-divider>
 
             <el-row v-if="isAll">
-                <el-col v-if="questionvo.type === 'short_answer'">
+                <el-col v-if="questionvo.type === 'short_answer'" class="correct_answer">
                     <MarkdownText :raw="'<strong>正确答案: </strong>'+questionvo.answer"></MarkdownText>
                 </el-col>
             </el-row>
@@ -249,7 +249,7 @@
     }
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
     .bQuestion-card{
         margin: 20px;
         font-family: "Times New Roman";

+ 49 - 18
src/components/card/QuestionUpdater.vue

@@ -80,13 +80,27 @@
                     </div>
                 </div>
                 <div v-else-if="question.type === 'blank'">
-                    <p>填空题</p>
+                    <div v-for="index in Object.keys(question.blanks).length">
+                        <el-row>
+                            <el-col :span="3">
+                                __{{index}}__:
+                            </el-col>
+                            <el-col :span="18">
+                                <el-input placeholder="填空项" v-model="question.blanks['__'+index+'__']"></el-input>
+                            </el-col>
+                        </el-row>
+                    </div>
                 </div>
                 <div v-else-if="question.type === 'short_answer'">
-                    <p>简答题</p>
+                    <el-input
+                            type="textarea"
+                            :rows="3"
+                            placeholder="answer"
+                            v-model="question.answer">
+                    </el-input>
                 </div>
                 <div v-else-if="question.type === 'true_false'">
-                    <p>判断题</p>
+                    <el-input placeholder="判断答案" v-model="question.answer"></el-input>
                 </div>
                 <div v-else-if="question.type === 'code'">
                     <p>编程题</p>
@@ -139,29 +153,18 @@
         </el-form>
         <div class="question-drawer__footer">
             <el-button @click="cancelForm">取 消</el-button>
-            <el-button type="primary" @click="submitNewQuestion" :loading="loading">{{ loading ? '提交中 ...' : '确 定' }}</el-button>
+            <el-button type="primary" @click="updateQuestion" :loading="loading">{{ loading ? '提交中 ...' : '确 定' }}</el-button>
         </div>
     </div>
 </template>
 
 <script>
+    import {updateQuestion} from "../../api/question";
+
     export default {
         name: "QuestionUpdater",
         props: {
-            question: {
-                id: String,
-                type: String,
-                stem: String,
-                options: Map,
-                answer: String,
-                keyPoints: String,
-                analysis: String,
-                tags: Array,
-                knowledgeId: Array,
-                weight: Number,
-                createdTime: Date,
-                lastModifiedTime: Date
-            }
+            question: Object
         },
         data(){
             return{
@@ -201,6 +204,34 @@
                 chosenTags: ["Java", "软工系列", "Python", "Vue", "SpringBoot"],
                 myknowledgeId: '',
             }
+        },
+        methods:{
+            cancelForm(){
+                this.$emit('closeDialog');
+            },
+            updateQuestion(){
+                this.question.lastModifiedTime = new Date();
+                updateQuestion(this.question).then(res => {
+                    console.log(res);
+                    this.$notify({
+                        title: '成功',
+                        message: '更新成功',
+                        type: 'success'
+                    });
+                    setTimeout(() => {
+                        this.$emit('closeDialog');
+                    }, 1000);
+                }).catch(err => {
+                    console.log(err);
+                    this.$notify.error({
+                        title: '错误',
+                        message: '更新失败'
+                    });
+                }).finally(() => {
+                    console.log('updateQuestion');
+                })
+
+            }
         }
     }
 </script>

+ 2 - 1
src/main.js

@@ -6,5 +6,6 @@ import store from './store'
 import ElementPlus from 'element-plus';
 import 'element-plus/lib/theme-chalk/index.css';
 
+let Vue = createApp(App);
 
-createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
+Vue.use(store).use(router).use(ElementPlus).mount('#app')

+ 1 - 0
src/utils/knowledgeMapper.js

@@ -13,5 +13,6 @@ function createMapper() {
 mapper = createMapper();
 
 export function map(abbreviation) {
+    // console.log(mapper);
     return mapper[abbreviation];
 }