ExerciseList.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <div class="ev-cp-list-container" style="width: 100%; margin: 0 auto">
  3. <!-- 筛选部分结束 -->
  4. <!-- 题目列表部分 -->
  5. <Loading :top="100" v-show="dataLoading" hideMask></Loading>
  6. <div v-if="exerciseList.length === 0" class="no-data-text">
  7. <img src="@/assets/icon/no_data_evaluation.png" width="120" />
  8. <span style="margin-top: 15px; color: #808080">暂无数据</span>
  9. </div>
  10. <div class="content-wrap" ref="mathJaxContainer" v-else>
  11. <div class="exercise-item" v-for="(item, index) of exerciseList" :key="index" @click="onQuestionToggle(index, item.id, $event)">
  12. <!-- 题干部分 -->
  13. <div class="item-question">
  14. <div>
  15. <div class="item-question-order">
  16. {{ pageSize * (pageNum - 1) + index + 1 }} :
  17. </div>
  18. <div class="item-question-text" v-html="item.question"></div>
  19. </div>
  20. <span class="item-btn-toggle">
  21. <Icon :type="collapseList.indexOf(index) > -1 ? 'ios-arrow-dropup' : 'ios-arrow-dropdown' " />
  22. </span>
  23. </div>
  24. <!-- 选项部分 -->
  25. <div v-for="(option, optionIndex) in item.option" :key="optionIndex" class="item-options">
  26. <div class="item-option-content">
  27. <div class="item-option-order">
  28. {{ String.fromCharCode(64 + parseInt(optionIndex + 1)) }} :
  29. </div>
  30. <div class="item-option-text" v-html="option.value"></div>
  31. </div>
  32. </div>
  33. <transition name="slide">
  34. <div v-show="collapseList.indexOf(exerciseList.indexOf(item)) > -1" class="toggle-area">
  35. <div v-if="item.type !== 'compose'">
  36. <!-- 答案展示部分 -->
  37. <div class="item-explain">
  38. <span class="explain-title">【答ㅤ案】</span>
  39. <div class="item-explain-details">
  40. <!-- 问答题答案 -->
  41. <div v-if="item.type === 'subjective' || item.type === 'complete'">
  42. <span v-for="(answer, index) in item.answer" :key="index" v-html="item.answer.length ? answer : '未设置答案'"></span>
  43. </div>
  44. <!-- 问答题答案 -->
  45. <div v-else-if="item.type === 'judge'">
  46. <span>{{ item.answer.length ? (item.answer[0] === 'A' ? '正确' : '错误') : '未设置答案' }}</span>
  47. </div>
  48. <!-- 其余题型答案 -->
  49. <div v-else>
  50. <span :class="[ item.type === 'complete' ? 'item-answer-item' : '' ]" v-for="(answer, index) in item.answer" :key="index">{{ answer }}</span>
  51. </div>
  52. </div>
  53. </div>
  54. <!-- 解析部分 -->
  55. <div class="item-explain">
  56. <span class="explain-title">【解ㅤ析】</span>
  57. <div class="item-explain-details">
  58. <span v-html="item.explain || '暂无解析'"></span>
  59. </div>
  60. </div>
  61. <!-- 知识点部分 -->
  62. <div class="item-explain">
  63. <span class="explain-title">【知识点】</span>
  64. <div class="item-explain-details">
  65. <span v-if="!item.points.length">暂未绑定知识点</span>
  66. <div v-else>
  67. <span v-for="(point, index) in item.points" class="item-point-tag" :key="index">
  68. {{ point }}
  69. </span>
  70. </div>
  71. </div>
  72. </div>
  73. </div>
  74. <!-- 如果是综合题 则加载子题渲染组件 -->
  75. <div v-else>
  76. <BaseChild :children="item.children"></BaseChild>
  77. </div>
  78. </div>
  79. </transition>
  80. <!-- 底部题目操作栏 -->
  81. <div class="item-tools">
  82. <span class="item-tools-info">题型:{{ exersicesType[item.type] }}</span>
  83. <span class="item-tools-info">难度:{{ exersicesDiff[item.level - 1] }}</span>
  84. <span class="item-tools-info">认知层次:{{ exersicesField[item.field - 1] }}</span>
  85. <span class="item-tools-info">使用次数:{{ item.usageCount || 0 }} 次</span>
  86. <Button type="info" :style="{backgroundColor:selectList.map(i => i.id).indexOf(item.id) > -1 ? '#bbbbbb' : '#2db7f5'}"
  87. @click.stop="onSelectItem(item,index)">{{ selectList.map(i => i.id).indexOf(item.id) > -1 ? '移除' : '选题'}}</Button>
  88. </div>
  89. </div>
  90. </div>
  91. <!-- 底部分页区域 -->
  92. <Page :total="totalNum" show-sizer show-total :page-size="pageSize" :current="pageNum" @on-page-size-change="pageSizeChange"
  93. @on-change="pageChange" :page-size-opts="[5, 10, 15, 20]" />
  94. </div>
  95. </template>
  96. <script>
  97. import blobTool from "@/utils/blobTool.js";
  98. export default {
  99. props:{
  100. propsList:{
  101. type:Array,
  102. default:() => {
  103. return []
  104. }
  105. },
  106. selQue: {
  107. type: Array,
  108. default: () => {
  109. return []
  110. }
  111. },
  112. },
  113. data() {
  114. return {
  115. dataLoading: true,
  116. exersicesType: {
  117. single: "单选题",
  118. multiple: "多选题",
  119. judge: "判断题",
  120. complete: "填空题",
  121. subjective: "问答题",
  122. compose: "综合题",
  123. },
  124. exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
  125. exersicesField:["知识", "理解", "应用", "分析", "综合", "评鉴"],
  126. diffColors: ["#32CF74", "#E8BE15", "#F19300", "#EB5E00", "#D30000"],
  127. totalNum: 0,
  128. isShowAnswer: true,
  129. importLoading: false,
  130. pageSize: 5,
  131. pageNum: 1,
  132. currentPage: 1,
  133. collapseList: [],
  134. selectList:[],
  135. originData: [],
  136. exerciseList:[]
  137. };
  138. },
  139. created() {
  140. console.log('接收到的',this.propsList)
  141. this.pageChange(1)
  142. },
  143. methods: {
  144. getBlobList(list){
  145. return new Promise(async (r,j) => {
  146. let blobList = await this.$evTools.getFullItem(list)
  147. r(blobList)
  148. })
  149. },
  150. onSelectItem(item,index){
  151. let arrIndex = this.selectList.map(i => i.id).indexOf(item.id)
  152. console.log(arrIndex)
  153. if(arrIndex > -1){
  154. this.selectList.splice(arrIndex,1)
  155. this.$Message.warning('取消成功!')
  156. }else{
  157. this.selectList.push(item)
  158. this.$Message.success('添加成功!')
  159. }
  160. this.$emit('on-question-change', this.selectList,0)
  161. console.log(this.selectList)
  162. console.log(item)
  163. },
  164. /**
  165. * 全部展开与全部折叠
  166. * @param isAllOpen
  167. */
  168. onHandleToggle(isAllOpen) {
  169. if (isAllOpen) {
  170. this.collapseList = [];
  171. } else {
  172. this.collapseList = [...this.exerciseList.keys()];
  173. }
  174. },
  175. /**
  176. * 题干展开与收缩
  177. * @param index
  178. * @param id
  179. */
  180. onQuestionToggle(index, id, e) {
  181. let curClassName = e.target.className;
  182. if (
  183. curClassName === "item-tools" ||
  184. curClassName === "richText-video" ||
  185. curClassName === "richText-audio"
  186. )
  187. return;
  188. e.stopPropagation();
  189. let listIndex = this.collapseList.indexOf(index);
  190. if (listIndex > -1) {
  191. this.collapseList.splice(listIndex, 1);
  192. } else {
  193. this.collapseList.push(index);
  194. let exerciseItemDom = e.path.filter(
  195. (i) => i.className === "exercise-item"
  196. );
  197. if (exerciseItemDom.length) {
  198. this.$emit("pageScroll", exerciseItemDom[0].offsetTop);
  199. }
  200. }
  201. this.$emit("toggleChange", this.collapseList);
  202. },
  203. /**
  204. * 删除筛选条件里面的False值与All值
  205. * @param arr
  206. */
  207. deleteFalse(arr) {
  208. let list = JSON.parse(JSON.stringify(arr));
  209. list.forEach((item, index) => {
  210. if (!item || item === "all") list.splice(index, 1);
  211. });
  212. return list;
  213. },
  214. /**
  215. * 切换页码操作
  216. * @param page
  217. */
  218. async pageChange(page) {
  219. this.dataLoading = true
  220. this.pageNum = page;
  221. let start = this.pageSize * (page - 1);
  222. let end = this.pageSize * page;
  223. // 拿到当前页码需要展示的数据
  224. this.$emit("pageScroll", 0);
  225. let simpleList = this.originData.slice(start, end);
  226. try {
  227. // 执行试题换取完整JSON数据
  228. this.exerciseList = await this.getBlobList(simpleList);
  229. this.currentPage = page;
  230. // 公式渲染
  231. this.$nextTick(() => {
  232. window.MathJax.Hub.Queue([
  233. "Typeset",
  234. MathJax.Hub,
  235. this.$refs.mathJaxContainer,
  236. ]);
  237. });
  238. setTimeout(() => {
  239. this.dataLoading = false
  240. },1000)
  241. } catch (e) {
  242. console.log(e);
  243. this.dataLoading = false
  244. }
  245. },
  246. /**
  247. * 切换每页显示数量
  248. * @param val
  249. */
  250. pageSizeChange(val) {
  251. this.pageSize = val;
  252. this.pageChange(1);
  253. },
  254. },
  255. mounted() {
  256. // 公式渲染
  257. this.$nextTick(() => {
  258. window.MathJax.Hub.Queue([
  259. "Typeset",
  260. MathJax.Hub,
  261. this.$refs.mathJaxContainer,
  262. ]);
  263. });
  264. // console.log('拿到已选',this.selQue)
  265. this.selectList = this.selQue
  266. // this.$EventBus.$off('onPaperItemChange')
  267. // this.$EventBus.$on('onPaperItemChange', data => {
  268. // console.log('EventBus',data)
  269. // this.selectList = data
  270. // })
  271. },
  272. computed: {
  273. curScope() {
  274. return this.filterOrigin === this.$store.state.userInfo.schoolCode ?
  275. "school" :
  276. "private";
  277. },
  278. hasSchool() {
  279. return this.$store.state.userInfo.hasSchool;
  280. },
  281. },
  282. watch:{
  283. propsList:{
  284. handler(n,o){
  285. if(n){
  286. console.log('监听到',n)
  287. this.originData = n
  288. this.totalNum = n.length
  289. this.pageChange(1)
  290. }
  291. }
  292. },
  293. selQue:{
  294. handler(n,o){
  295. if(n){
  296. console.log('监听到222',n)
  297. }
  298. }
  299. },
  300. }
  301. };
  302. </script>
  303. <style src="./ExerciseList.less" lang="less" scoped>
  304. </style>
  305. <style>
  306. .circle {
  307. border: solid 1px red;
  308. background-color: red;
  309. border-radius: 50%;
  310. width: 50px;
  311. height: 50px;
  312. }
  313. .slide-enter-active {
  314. transition: all 0.3s ease;
  315. }
  316. .slide-leave-active {
  317. transition: all 0.3s ease;
  318. }
  319. .slide-enter,
  320. .slide-leave-to {
  321. transform: translateY(10px);
  322. opacity: 0;
  323. }
  324. </style>