QuestionTable.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <div class="question-table">
  3. <search-bar class="mb-16" v-model="inputStem" placeholder="题干搜索" @input="debounceFetchQuestions"/>
  4. <pagination class="mt-16 mb-32" :page="page.number" :size="page.size" :total-elements="page.totalElements"
  5. v-show="questionList && questionList.length > 0" @change="fetchQuestionList"></pagination>
  6. <div class="no-content-warning" v-if="questionList === null || questionList.length === 0">请输入关键字搜索</div>
  7. <div class="question-card-container" v-else>
  8. <template v-for="item in questionList">
  9. <question-card
  10. v-if="item !== null"
  11. :key="item.id"
  12. :editable="ownQuestionIds.indexOf(item.id) !== -1"
  13. :type="item.type"
  14. :stem="item.stem"
  15. :question-id="item.id"
  16. :selectable="selectable"
  17. :selected="judgeIsSelected(item)"
  18. @toggle-select="handleToggleSelectQuestion(item)"
  19. />
  20. </template>
  21. </div>
  22. </div>
  23. </template>
  24. <script>
  25. import debounce from '@/utils/debounce'
  26. import { getCreatedQuestionIds, getCreatedQuestions, getQuestionList } from '@/server/question'
  27. import Pagination from '@/components/Pagination'
  28. import { markdownToHTML } from '@/utils/markdown'
  29. import QuestionCard from '@/views/quiz/components/QuestionCard'
  30. import SearchBar from '@/components/Basic/SearchBar'
  31. export default {
  32. name: 'QuestionTable',
  33. components: { SearchBar, QuestionCard, Pagination },
  34. props: {
  35. selectable: {
  36. type: Boolean,
  37. default: false
  38. },
  39. selectedQuestions: {
  40. type: Array,
  41. default: () => []
  42. },
  43. showOwn: {
  44. type: Boolean,
  45. default: false
  46. }
  47. },
  48. model: {
  49. prop: 'selectedQuestions',
  50. event: 'select'
  51. },
  52. filters: {
  53. markdownToHTML: markdownToHTML
  54. },
  55. watch: {
  56. showOwn () {
  57. this.fetchQuestionList()
  58. }
  59. },
  60. data () {
  61. return {
  62. inputStem: '',
  63. questionList: [],
  64. ownQuestionList: [],
  65. // 该属性与上面属性不同之处在于所有id是一次全拿的
  66. // List为分页获取,因此不能用于判断这个问题是否能够编辑
  67. ownQuestionIds: [],
  68. page: {},
  69. // 模糊搜索时使用
  70. debounceFetchQuestions: debounce(() => this.fetchQuestionList())
  71. }
  72. },
  73. mounted () {
  74. this.fetchQuestionList()
  75. this.fetchOwnQuestionIds()
  76. },
  77. methods: {
  78. fetchQuestionList ({
  79. stem = this.inputStem,
  80. page = 1,
  81. size = 10
  82. } = {}) {
  83. this.showOwn
  84. ? getCreatedQuestions({ key: stem, size, page })
  85. .then(({ data: questions, page }) => {
  86. this.questionList = questions
  87. this.page = page
  88. })
  89. : getQuestionList({ key: stem, size, page })
  90. .then(({ data: questions, page }) => {
  91. this.questionList = questions
  92. this.page = page
  93. })
  94. },
  95. fetchOwnQuestionIds () {
  96. getCreatedQuestionIds()
  97. .then(res => (this.ownQuestionIds = res))
  98. .catch(err => this.$setErrorMessage(err.response.data.msg))
  99. },
  100. judgeIsSelected (question) {
  101. return Boolean(this.selectedQuestions
  102. .find(item => item.id === question.id))
  103. },
  104. handleToggleSelectQuestion (question) {
  105. if (this.judgeIsSelected(question)) {
  106. this.$emit('select', this.selectedQuestions.filter(item => item.id !== question.id))
  107. } else {
  108. this.$emit('select', [...this.selectedQuestions, question])
  109. }
  110. }
  111. }
  112. }
  113. </script>
  114. <style lang="scss" scoped>
  115. .question-card-container {
  116. column-width: 300px;
  117. column-gap: 24px;
  118. }
  119. .question-card {
  120. margin-bottom: 24px;
  121. break-inside: avoid;
  122. border-radius: 6px;
  123. border: 1px solid #cadaea;
  124. /*box-shadow: 0 2px 6px rgba(0, 0, 0, .1);*/
  125. }
  126. </style>