完成全部功能
This commit is contained in:
		| @@ -1,12 +1,13 @@ | ||||
| <template> | ||||
|   <v-app> | ||||
|     <!--    src="https://api.ixiaowai.cn/api/api.php"--> | ||||
|     <v-app-bar app :dark="useDarkTheme"> | ||||
|       <v-app-bar-nav-icon></v-app-bar-nav-icon> | ||||
|     <v-app-bar app> | ||||
|       <v-app-bar-nav-icon @click="navigateToHome"> | ||||
|         <v-icon>mdi-home</v-icon> | ||||
|       </v-app-bar-nav-icon> | ||||
|       <v-toolbar-title class="text-h5">slader-legacy</v-toolbar-title> | ||||
|       <v-spacer></v-spacer> | ||||
|       <v-btn icon> | ||||
|         <v-icon @click="useDarkTheme=!useDarkTheme">mdi-brightness-6</v-icon> | ||||
|         <v-icon @click="toggleDarkTheme">mdi-brightness-6</v-icon> | ||||
|       </v-btn> | ||||
|     </v-app-bar> | ||||
|     <v-main> | ||||
| @@ -14,7 +15,10 @@ | ||||
|         <v-row justify="center"> | ||||
|           <v-col md="8" sm="12"> | ||||
|             <v-card :loading="cardLoading"> | ||||
|               <router-view @loadingSignal="cardLoadingCompleted" class="pa-4"></router-view> | ||||
|               <keep-alive> | ||||
|                 <router-view @setCardLoadingStatus="handleSetCardLoadingStatus" class="pa-4"></router-view> | ||||
|               </keep-alive> | ||||
|  | ||||
|             </v-card> | ||||
|           </v-col> | ||||
|         </v-row> | ||||
| @@ -22,7 +26,7 @@ | ||||
|     </v-main> | ||||
|     <v-footer padless> | ||||
|       <v-col cols="12" class="text-center"> | ||||
|         slader-legacy {{new Date().getFullYear()}} | ||||
|         slader-legacy {{ new Date().getFullYear() }} | ||||
|       </v-col> | ||||
|     </v-footer> | ||||
|   </v-app> | ||||
| @@ -31,7 +35,7 @@ | ||||
| <script> | ||||
|  | ||||
| import TextbookBlock from "@/components/TextbookBlock" | ||||
| import {showServerErrorAlert} from "@/includes" | ||||
| import {cardLoadingStatusCheck, showServerErrorAlert} from "@/includes" | ||||
|  | ||||
| export default { | ||||
|   name: 'App', | ||||
| @@ -40,17 +44,20 @@ export default { | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       useDarkTheme: false, | ||||
|       cardLoading: true | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|   }, | ||||
|   methods: { | ||||
|     cardLoadingCompleted(status) { | ||||
|       if (status) { | ||||
|         this.cardLoading = false | ||||
|       } else { | ||||
|         showServerErrorAlert() | ||||
|       } | ||||
|     handleSetCardLoadingStatus(status) { | ||||
|       this.cardLoading = status | ||||
|     }, | ||||
|     navigateToHome() { | ||||
|       this.$router.push('/') | ||||
|     }, | ||||
|     toggleDarkTheme() { | ||||
|       this.$vuetify.theme.dark = !this.$vuetify.theme.dark | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,16 @@ | ||||
|  | ||||
|   <v-card outlined shaped hover height="329"> | ||||
|     <div @click="openTextbook"> | ||||
|       <v-img :src="imgSrc" height="210"></v-img> | ||||
|       <v-img :src="imgSrc" height="210"> | ||||
|         <template #placeholder> | ||||
|           <v-row class="fill-height" align="center" justify="center"> | ||||
|           <v-progress-circular | ||||
|               indeterminate | ||||
|               color="primary" | ||||
|           ></v-progress-circular> | ||||
|           </v-row> | ||||
|         </template> | ||||
|       </v-img> | ||||
|       <v-card-subtitle class="text-truncate subtitle-2"> | ||||
|         {{ textbookTitleRefined }} | ||||
|       </v-card-subtitle> | ||||
| @@ -33,8 +42,8 @@ import {textbookTitleRefine} from "@/includes" | ||||
|  | ||||
| export default { | ||||
|   name: "TextbookBlock", | ||||
|   computed:{ | ||||
|     textbookTitleRefined(){ | ||||
|   computed: { | ||||
|     textbookTitleRefined() { | ||||
|       return textbookTitleRefine(this.title) | ||||
|     } | ||||
|   }, | ||||
|   | ||||
| @@ -11,6 +11,14 @@ | ||||
|       ><p class="font-weight-bold text-h5 mb-0 mx-5">题 {{ exercise }}</p></v-badge> | ||||
|     </v-row> | ||||
|     <div class="mt-5" v-html="myHtml"></div> | ||||
|     <v-btn v-if="hasPreviousExercise" @click="goToExercise(previousExerciseIndex)" fab bottom left icon fixed | ||||
|            elevation="2" color="green"> | ||||
|       <v-icon>mdi-arrow-left</v-icon> | ||||
|     </v-btn> | ||||
|     <v-btn v-if="hasNextExercise" @click="goToExercise(nextExerciseIndex)" fab bottom right icon fixed elevation="2" | ||||
|            color="green"> | ||||
|       <v-icon>mdi-arrow-right</v-icon> | ||||
|     </v-btn> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| @@ -20,7 +28,63 @@ import {showServerErrorAlert} from "@/includes" | ||||
|  | ||||
| export default { | ||||
|   name: "Exercise", | ||||
|   async created() { | ||||
|   created() { | ||||
|     this.getExercise() | ||||
|   }, | ||||
|   watch:{ | ||||
|     exercise(){ | ||||
|       console.log('watch exercise trigger') | ||||
|       this.getExercise() | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     badgeContent() { | ||||
|       return this.section + ' - ' + this.myPage | ||||
|     }, | ||||
|     tableDataIndex() { | ||||
|       if (!this.tableData) { | ||||
|         return false | ||||
|       } | ||||
|       return this.tableData.findIndex(single => single.exercise === this.exercise) | ||||
|     }, | ||||
|     hasPreviousExercise(){ | ||||
|       return this.previousExerciseIndex !== false; | ||||
|     }, | ||||
|     hasNextExercise(){ | ||||
|       return this.nextExerciseIndex !== false; | ||||
|     }, | ||||
|     previousExerciseIndex() { | ||||
|       if (this.tableDataIndex === false || this.tableDataIndex === 0) { | ||||
|         return false | ||||
|       } | ||||
|       return this.tableDataIndex - 1 | ||||
|     }, | ||||
|     nextExerciseIndex() { | ||||
|       if (this.tableDataIndex === false || this.tableDataIndex === this.tableData.length - 1) { | ||||
|         return false | ||||
|       } | ||||
|       return this.tableDataIndex + 1 | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     textbook: String, | ||||
|     section: String, | ||||
|     exercise: [String, Number], | ||||
|     page: Number, | ||||
|     part: String, | ||||
|     html: String, | ||||
|     tableData: Array | ||||
|   }, | ||||
|   methods: { | ||||
|     goToExercise(exerciseIndex) { | ||||
|       this.$router.push({name: 'exercise', params: {...this.tableData[exerciseIndex], tableData: this.tableData}}) | ||||
|     }, | ||||
|     returnToSection() { | ||||
|       this.$router.push({name: 'section', params: {textbook: this.textbook, section: this.section}}) | ||||
|     }, | ||||
|     async getExercise() { | ||||
|       this.$emit('setCardLoadingStatus', true) | ||||
|       console.log('get exercise') | ||||
|       if (!this.html) { | ||||
|         let resp = await myAxios.get('textbook/' + this.textbook + '/' + encodeURIComponent(this.section) + '/' + this.exercise) | ||||
|         if (!resp.data.status) { | ||||
| @@ -30,26 +94,12 @@ export default { | ||||
|         this.myHtml = resp.data.data.html | ||||
|         this.myPage = resp.data.data.page | ||||
|         this.myPart = resp.data.data.part || 'exercises' | ||||
|       } else { | ||||
|         this.myHtml = this.html | ||||
|         this.myPage = this.page | ||||
|         this.myPart = this.part | ||||
|       } | ||||
|  | ||||
|     this.$emit('loadingSignal', true) | ||||
|   }, | ||||
|   computed: { | ||||
|     badgeContent() { | ||||
|       return this.section + ' - ' + this.myPage | ||||
|     } | ||||
|   }, | ||||
|   props: { | ||||
|     textbook: String, | ||||
|     section: String, | ||||
|     exercise: [String, Number], | ||||
|     page: Number, | ||||
|     part: String, | ||||
|     html: String | ||||
|   }, | ||||
|   methods: { | ||||
|     returnToSection() { | ||||
|       this.$router.push({name: 'section', params: {textbook: this.textbook, section: this.section}}) | ||||
|       this.$emit('setCardLoadingStatus', false) | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
| @@ -63,23 +113,27 @@ export default { | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
| .inline-picture-name{ | ||||
| .inline-picture-name { | ||||
|   margin: 50px 0; | ||||
|   border-top: 5px gray solid; | ||||
|   padding-top: 20px; | ||||
| } | ||||
|  | ||||
| .inline-picture-name img { | ||||
|   display: inline-block; | ||||
|   width: 50px; | ||||
|   height: 50px; | ||||
| } | ||||
| .object-ratings-wrap{ | ||||
|  | ||||
| .object-ratings-wrap { | ||||
|   display: none; | ||||
| } | ||||
| .open-comments{ | ||||
|  | ||||
| .open-comments { | ||||
|   display: none; | ||||
| } | ||||
| .row-counter{ | ||||
|  | ||||
| .row-counter { | ||||
|   width: 100%; | ||||
|   background-color: whitesmoke; | ||||
|   text-align: center; | ||||
| @@ -87,40 +141,50 @@ export default { | ||||
|   border-bottom: black 1px solid; | ||||
|   margin: 5px 0; | ||||
| } | ||||
| .result-heading{ | ||||
|  | ||||
| .result-heading { | ||||
|   display: block; | ||||
|   font-size: 25px; | ||||
|   font-weight: bold; | ||||
| } | ||||
| .solution-content img{ | ||||
|  | ||||
| .solution-content img { | ||||
|   max-width: 90%; | ||||
|   border: 1px solid black; | ||||
|   display: block; | ||||
|   margin: 10px auto; | ||||
| } | ||||
| .image-reg{ | ||||
|   display: none!important; | ||||
|  | ||||
| .image-reg { | ||||
|   display: none !important; | ||||
| } | ||||
| .unfinished-hover{ | ||||
|  | ||||
| .unfinished-hover { | ||||
|   display: none; | ||||
| } | ||||
| .annotations{ | ||||
|  | ||||
| .annotations { | ||||
|   display: none; | ||||
| } | ||||
| .comment-footer{ | ||||
|  | ||||
| .comment-footer { | ||||
|   display: none; | ||||
| } | ||||
| .center{ | ||||
|  | ||||
| .center { | ||||
|   text-align: center; | ||||
| } | ||||
| .solution-content p{ | ||||
|  | ||||
| .solution-content p { | ||||
|   font-size: 20px; | ||||
|   font-family: "Times New Roman",serif; | ||||
|   font-family: "Times New Roman", serif; | ||||
| } | ||||
| .Paywall__footer-counter{ | ||||
|  | ||||
| .Paywall__footer-counter { | ||||
|   display: none; | ||||
| } | ||||
| .edit-toolbar{ | ||||
|  | ||||
| .edit-toolbar { | ||||
|   display: none; | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| <script> | ||||
| import TextbookBlock from "@/components/TextbookBlock" | ||||
| import {myAxios} from "@/includes" | ||||
| import {showServerErrorAlert} from "@/includes" | ||||
|  | ||||
| export default { | ||||
|   name: 'Home', | ||||
| @@ -16,10 +17,13 @@ export default { | ||||
|     myAxios.get('textbook').then(resp => { | ||||
|       if (resp.data.status) { | ||||
|         this.textbooks = resp.data.data | ||||
|       }else{ | ||||
|         showServerErrorAlert() | ||||
|       } | ||||
|       this.$emit('loadingSignal',resp.data.status) | ||||
|       this.$emit('setCardLoadingStatus',!resp.data.status) | ||||
|     }).catch(reason => { | ||||
|       this.$emit('loadingSignal',false) | ||||
|       showServerErrorAlert() | ||||
|       this.$emit('setCardLoadingStatus',true) | ||||
|     }) | ||||
|   }, | ||||
|   components: { | ||||
|   | ||||
| @@ -16,21 +16,18 @@ import {myAxios} from '@/includes' | ||||
| export default { | ||||
|   name: "Section", | ||||
|   components: {StandardTable}, | ||||
|   computed:{ | ||||
|     textbookSection(){ | ||||
|       return this.textbook+this.section | ||||
|     } | ||||
|   }, | ||||
|   watch:{ | ||||
|     textbookSection(){ | ||||
|       this.getSection() | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     myAxios.get('textbook/' + this.textbook + '/' + encodeURIComponent(this.section)).then(resp => { | ||||
|       if (resp.data.status) { | ||||
|         this.tableData = resp.data.data.map(single => { | ||||
|           let modified = single | ||||
|           if (!modified.part) { | ||||
|             modified.part = 'exercises' | ||||
|           } | ||||
|           return modified | ||||
|         }) | ||||
|       } | ||||
|       this.$emit('loadingSignal', resp.data.status) | ||||
|     }).catch(reason => { | ||||
|       this.$emit('loadingSignal', false) | ||||
|     }) | ||||
|     this.getSection() | ||||
|   }, | ||||
|   props: { | ||||
|     textbook: String, | ||||
| @@ -43,7 +40,26 @@ export default { | ||||
|     openExercise(item) { | ||||
|       this.$router.push({ | ||||
|         name: 'exercise', | ||||
|         params: {...item} | ||||
|         params: {...item, tableData: this.tableData} | ||||
|       }) | ||||
|     }, | ||||
|     getSection() { | ||||
|       this.$emit('setCardLoadingStatus', true) | ||||
|       console.log('ajax get section') | ||||
|       this.tableData = [] | ||||
|       myAxios.get('textbook/' + this.textbook + '/' + encodeURIComponent(this.section)).then(resp => { | ||||
|         if (resp.data.status) { | ||||
|           this.tableData = resp.data.data.map((single, index, array) => { | ||||
|             let modified = single | ||||
|             if (!modified.part) { | ||||
|               modified.part = 'exercises' | ||||
|             } | ||||
|             return modified | ||||
|           }) | ||||
|         } | ||||
|         this.$emit('setCardLoadingStatus', !resp.data.status) | ||||
|       }).catch(reason => { | ||||
|         this.$emit('setCardLoadingStatus', true) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import {textbookTitleRefine} from "@/includes" | ||||
| import {myAxios} from "@/includes" | ||||
| import Swal from "sweetalert2" | ||||
| import StandardTable from "@/components/StandardTable" | ||||
| import {showServerErrorAlert} from "@/includes" | ||||
|  | ||||
| export default { | ||||
|   name: "Textbook", | ||||
| @@ -22,15 +23,21 @@ export default { | ||||
|       return textbookTitleRefine(this.textbook) | ||||
|     } | ||||
|   }, | ||||
|   watch:{ | ||||
|     textbook(){ | ||||
|       this.getTextbook() | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     goToHomePage() { | ||||
|       this.$router.push('/') | ||||
|     }, | ||||
|     openSection(item) { | ||||
|       this.$router.push({name: 'section', params: {textbook: this.textbook, section: item.section}}) | ||||
|     } | ||||
|     }, | ||||
|   created() { | ||||
|     getTextbook(){ | ||||
|       this.$emit('setCardLoadingStatus', true) | ||||
|       this.tableData=[] | ||||
|       if (!this.textbook) { | ||||
|         Swal.fire({ | ||||
|           title: '错误', | ||||
| @@ -42,11 +49,17 @@ export default { | ||||
|       myAxios.get('textbook/' + this.textbook).then(resp => { | ||||
|         if (resp.data.status) { | ||||
|           this.tableData = resp.data.data | ||||
|         }else{ | ||||
|           showServerErrorAlert() | ||||
|         } | ||||
|       this.$emit('loadingSignal', resp.data.status) | ||||
|         this.$emit('setCardLoadingStatus', !resp.data.status) | ||||
|       }).catch(reason => { | ||||
|       this.$emit('loadingSignal', false) | ||||
|         this.$emit('setCardLoadingStatus', true) | ||||
|       }) | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.getTextbook() | ||||
|   }, | ||||
|   props: { | ||||
|     textbook: String | ||||
|   | ||||
		Reference in New Issue
	
	Block a user