amtoaer

晓风残月

叹息似的渺茫,你仍要保存着那真!
github
x
telegram
steam
nintendo switch
email

Marxist Theory and Mao Zedong Thought Review Tool (WEB VERSION)

title: Ma Yuan Mao Gai Brushing Tool (WEB VERSION)
date: 2020-01-30 09:44:08
tags: [website, go, Vue.js]
categories: Development Record
photos: /img/banner/images/12.jpg
description: A brushing tool developed using Vue.js and Go

Before the exam, I quickly developed a brushing tool for Ma Yuan. After the exam, I had some time to expand it into a Ma Yuan Mao Gai brushing tool (https://github.com/jeasonlau/Question-test). I added features such as random brushing, exam simulation, and a question bank. However, to be honest, the command-line program in Python was not very user-friendly. Therefore, I decided to convert it into a web version. The project (https://github.com/jeasonlau/Question-test-web) has been open-sourced on GitHub. (I had no previous experience with front-end development, so there may be many shortcomings.)

Backend#

The backend uses the lightweight web framework Gin in Go. The code can be found here: (https://github.com/jeasonlau/Question-test-web/blob/master/back-end/main.go)!

It reads the "mayuan.json/maogai.json" files in the current directory and returns different results based on different routes:

RouteResult
/$subject/position/Returns the question at the specified position for the subject
/$subject/random/Returns a random question for the subject
/$subject/random/radioReturns a random multiple-choice question for the subject
/$subject/random/checkboxReturns a random multiple-choice question for the subject

Frontend#

The frontend uses Vue.js. When I was preparing to learn it, I found this sentence in the official documentation:

The official guide assumes intermediate knowledge of HTML, CSS, and JavaScript. If you are just starting to learn frontend development, using a framework as your first step may not be the best idea - master the basics first! Previous experience with other frameworks can be helpful, but it is not required.

Since I had no knowledge of frontend development, I first learned HTML basics and the first few sections of CSS on FreeCodeCamp. Then, I learned JavaScript up to the functions part on Liao Xuefeng's tutorial. After that, I started developing while referring to the official documentation.


First, I used the webpack scaffolding to create a Vue project and then installed and imported the Muse-UI component library.

  1. Routing

    import Vue from 'vue'
    import Router from 'vue-router'
    import index from '../components/index'
    import temp from '../components/temp'
    import exam from '../components/exam'
    import order from '../components/order'
    import about from '../components/about'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'index',
          component: index
        },
        {
          path: '/马原',
          name: 'mayuan',
          component: temp
        },
        {
          path: '/毛概',
          name: 'maogai',
          component: temp
        },
        {
          path: '/马原/顺序刷题',
          name: 'mayuanorder',
          component: order
        },
        {
          path: '/毛概/顺序刷题',
          name: 'maogaiorder',
          component: order
        },
        {
          path: '/马原/考试模拟',
          name: 'mayuanexam',
          component: exam
        },
        {
          path: '/毛概/考试模拟',
          name: 'maogaiexam',
          component: exam
        },
        {
          path: '/关于',
          name: 'about',
          component: about
        }
      ]
    })
    
  2. Components

    • In App.vue, I wrote the common top bar, sidebar, and other content, and listened for route changes to modify the title.

    • index.vue and about.vue were written using pure HTML/CSS.

    • temp.vue is used to select the brushing method.

    • order.vue is the interface for sequential brushing, using mu-pagination for pagination. exam.vue is the interface for exam simulation, using mu-load-more to load the question part.

    • question.vue is a unit question and is a child component of order.vue and exam.vue. It listens for changes in the num prop, calls getQuestion() to load the corresponding question, and determines whether it is a multiple-choice or a multiple-selection question. The ifRight() function is used to check if the answer is correct when selecting an option.

      // ifRight
      ifRight: function () {
              let answer
              if (this.isRadio === false) {// For multiple-selection questions, sort and join the answer array into a string
                answer = this.yourAnswer.sort().join("")
              } else {// For multiple-choice questions, directly get the answer
                answer = this.yourAnswer
              }
              if (answer === this.question["Answer"]) {
                this.isRight = true
                let that = this
                if (this.timer)
                  clearTimeout(this.timer)
                this.timer = setTimeout(function () {// Display a notification for 2 seconds
                  that.isRight = false
                }, 2000)
              } else {
                this.isRight = false
              }
            }
      // getQuestion
      getQuestion () {
          this.yourAnswer=[]
          // Get the request URL based on the parent component's path and the current num
          if (this.type === "/马原/顺序刷题") {
              this.url = "https://.../api/mayuan/position/" + (this.num - 1)
          } else if (this.type === "/毛概/顺序刷题") {
              this.url = "https://.../api/maogai/position/" + (this.num - 1)
          } else if (this.type === "/马原/考试模拟") {
              if (this.num <= 40) {
                  this.url = "https://.../api/mayuan/random/radio"
              } else {
                  this.url= "https://.../api/mayuan/random/checkbox"
              }
          } else if (this.type === "/毛概/考试模拟") {
              if (this.num <= 40) {
                  this.url = "https://.../api/maogai/random/radio"
              } else {
                  this.url = "https://.../api/maogai/random/checkbox"
              }
          }
          axios// Use axios to request the API and get the question
              .get(this.url)
              .then(response => {
              this.question = response.data
              if (this.question['Answer'].length > 1) {// Determine if it is a multiple-choice or a multiple-selection question
                  this.isRadio = false
              } else {
                  this.isRadio = true
              }
          })
      }
      

Deployment#

I encountered several issues during deployment.

When I started debugging locally, I found that the questions were not being loaded. I checked the error messages in the Chrome console and found that it was because the backend did not have cross-origin resource sharing (CORS) configured. So I added the following line to the backend routes:

c.Writer.Header().Set("Access-Control-Allow-Origin", "*")

The debugging worked fine, but after deploying to GitHub Pages, I found that the questions still couldn't be loaded. Checking the error messages, I learned that in an HTTPS webpage, HTTP resources cannot be loaded. So, the task became adding HTTPS to Gin.

After researching, I found that the general method is to apply for a subdomain and a free certificate. However, I didn't want to go through all that trouble, and I happened to have an HTTPS domain. So, I simply set up a reverse proxy in the current server block of Nginx:

location /api{
        proxy_pass http://localhost:8080;
}

Then, I made requests to this address in GitHub Pages. However, I'm not sure if it was because of the intermediate Nginx, but I encountered another CORS issue. I couldn't find a solution immediately, so I had to deploy the frontend on Nginx as well to solve the problem (the only issue was that my server was not registered, so I had to manually enter the port to access it).

References#

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.