random.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <template>
  2. <view class="content" :class="{night:nightFlag}">
  3. <view class="top-box">
  4. <view class="icon"></view>
  5. <selectSwitch class='btn' @change="changeSwitch" :defaultSwitch='kemu==1' :switchList="['科一题目','科四题目']" checked_bj_color='#E31818' />
  6. <van-icon class='set' name="/static/imgs/设置.png" size='20' @click='show=true' />
  7. </view>
  8. <van-popup :show="show" @close="show=false" position="bottom">
  9. <van-cell title="背题模式" clickable :data-index="index" @click="answerflag=!answerflag">
  10. <van-switch slot="right-icon" :checked="answerflag" size="24px" active-color="#16CC16" />
  11. <!-- <selectSwitch slot="right-icon" @change="changeSwitch" :switchList="['答题模式','背题模式']" checked_bj_color='#E31818' /> -->
  12. </van-cell>
  13. <van-cell title="答对跳转下一题 " clickable :data-index="index" @click="answerjump=!answerjump">
  14. <van-switch slot="right-icon" :checked="answerjump" size="24px" active-color="#16CC16" />
  15. </van-cell>
  16. <!-- <van-cell title="答错展示题目解析" clickable :data-index="index" @click="checked=!checked">
  17. <van-switch slot="right-icon" :checked="checked" size="24px" active-color="#16CC16" />
  18. </van-cell> -->
  19. <van-cell title="错误震动提醒" clickable :data-index="index" @click="checked=!checked">
  20. <van-switch slot="right-icon" :checked="checked" size="24px" active-color="#16CC16" />
  21. </van-cell>
  22. <van-cell title="夜间模式" clickable :data-index="index" @click="nightFlag=!nightFlag">
  23. <van-switch slot="right-icon" :checked="nightFlag" size="24px" active-color="#16CC16" />
  24. </van-cell>
  25. <!-- <van-cell title="主题选择" clickable :data-index="index" @click="checked=!checked">
  26. <van-switch slot="right-icon" :checked="checked" size="24px" active-color="#16CC16" />
  27. </van-cell>
  28. <van-cell title="字体选择" clickable :data-index="index" @click="checked=!checked">
  29. <van-switch slot="right-icon" :checked="checked" size="24px" active-color="#16CC16" />
  30. </van-cell> -->
  31. </van-popup>
  32. <van-skeleton class='skeleton' avatar row="6" :row-width="['100%','40%','70%','70%','70%','70%']" avatar-shape='square'
  33. :loading="loading">
  34. <swiper class="swiper-box" :current="swiperIndex" @change="swiperChange" circular>
  35. <swiper-item v-for="(itembox,indexbox) in questionList" :key='indexbox'>
  36. <view class="swiper-item">
  37. <view class="topic-box">
  38. <view class="topic-right">
  39. <view class="topic-top">
  40. <view class="topic-left">
  41. <text class="topic-type">{{questionType(itembox.type)}}</text>
  42. <van-icon name="star-o" size='20' @tap='markQuestion(itembox.id)'/>
  43. </view>
  44. <!-- <rich-text class="topic-tit" :nodes="itembox.id+'、'+itembox.question"></rich-text> -->
  45. <view class="topic-tit" v-html="itembox.id+'、'+itembox.question"></view>
  46. </view>
  47. <video v-if="itembox.videoUrl" class="topic-img" :muted='true' :loop='true' :autoplay='true' :controls='false'
  48. :src="encodeURI(itembox.mediaUrl)"></video>
  49. <image v-if="itembox.sinaimg" class="topic-img" :src="itembox.mediaUrl" mode="aspectFit"></image>
  50. <view class="topic-opt" v-if='itembox.type==2'>
  51. <van-radio-group :value="userAnswer[itembox.id]">
  52. <van-cell-group>
  53. <van-cell :class='{answer:(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))}'
  54. v-for="(item,index) in choiceList" :key="index" :title="itembox[item]" v-show='itembox[item]' clickable
  55. :data-index="index+1" @click="singleToggle($event,itembox)">
  56. <van-icon v-if="(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))" slot="icon"
  57. name="/static/imgs/对.png" size='20' />
  58. <van-radio slot="right-icon" :ref="`checkboxes${itembox.id}`" checked-color="#1464cc" :name="index+1" />
  59. </van-cell>
  60. </van-cell-group>
  61. </van-radio-group>
  62. <!-- <button @click="submit(itembox)" class="submit" type="default" v-show="!(answerflag || completeAnswer[itembox.id])">提交答案</button> -->
  63. </view>
  64. <view class="topic-opt" v-if='itembox.type==1'>
  65. <van-radio-group :value="userAnswer[itembox.id]">
  66. <van-cell-group>
  67. <van-cell :class='{answer:(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))}'
  68. v-for="(item,index) in 2" :key="index" :title="index?'错误':'正确'" clickable :data-index="index+1" @click="singleToggle($event,itembox)">
  69. <van-icon v-if="(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))" slot="icon"
  70. name="/static/imgs/对.png" size='20' />
  71. <van-radio slot="right-icon" :ref="`checkboxes${itembox.id}`" checked-color="#1464cc" :name="index+1" />
  72. </van-cell>
  73. </van-cell-group>
  74. </van-radio-group>
  75. <!-- <button @click="submit(itembox)" class="submit" type="default" v-show="!(answerflag || completeAnswer[itembox.id])">提交答案</button> -->
  76. </view>
  77. <view class="topic-opt" v-else-if='itembox.type==3'>
  78. <van-checkbox-group :value="userAnswer[itembox.id]" @change="onChange($event,itembox)">
  79. <van-cell-group>
  80. <van-cell :class='{answer:(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))}'
  81. v-for="(item,index) in choiceList" :key="index" :title="itembox[item]" v-show='itembox[item]' clickable
  82. @click='toggle($event,itembox)' :data-index="index">
  83. <van-icon v-if="(itembox.answerTrue.includes(index+1) && (answerflag || completeAnswer[itembox.id]))" slot="icon"
  84. name="/static/imgs/对.png" size='20' />
  85. <van-checkbox shape="square" catch:tap="noop" slot="right-icon" :ref="`checkboxes${itembox.id}`"
  86. checked-color="#1464cc" :name="index+1" />
  87. </van-cell>
  88. </van-cell-group>
  89. </van-checkbox-group>
  90. <button @click="submit(itembox)" class="submit" type="default" v-show="!(answerflag || completeAnswer[itembox.id])">提交答案</button>
  91. </view>
  92. </view>
  93. </view>
  94. <view v-show="answerflag || completeAnswer[itembox.id]">
  95. <view class="flag">
  96. <text v-if="itembox.type==2" class="result">正确答案: {{itembox[choiceList[itembox.answerTrue-1]]}}</text>
  97. <text v-else-if="itembox.type==1" class="result">正确答案: {{itembox.answerTrue==1?'正确':'错误'}}</text>
  98. <text v-else-if="itembox.type==3" class="result">正确答案: {{itembox.answerTrue.split('').map((key)=>{
  99. return itembox[choiceList[key-1]]
  100. })}}</text>
  101. </view>
  102. <view class="parsing">
  103. <view class="item-titBox">
  104. <text class="item-tit">题目解析</text>
  105. </view>
  106. <view class="parsing-text">
  107. <text class="item-tit">{{itembox.explain1 ? itembox.explain1 : "无"}}</text>
  108. </view>
  109. </view>
  110. </view>
  111. </view>
  112. </swiper-item>
  113. </swiper>
  114. </van-skeleton>
  115. </view>
  116. </template>
  117. <script>
  118. import selectSwitch from "@/components/xuan-switch/xuan-switch.vue";
  119. import {
  120. questionListRandom,
  121. questionErrorAdd,
  122. questionErrorDel
  123. } from "@/api/answer.js"
  124. export default {
  125. components: {
  126. selectSwitch
  127. },
  128. data() {
  129. return {
  130. loading: true,
  131. answerflag: false,
  132. answerjump: true,
  133. nightFlag: false,
  134. kemu: uni.getStorageSync('kemu') || 1,
  135. completeAnswer: {},
  136. show: false,
  137. checked: true,
  138. radio: null,
  139. result: [],
  140. userAnswer: {},
  141. questionList: {},
  142. choiceList: ['an1', 'an2', 'an3', 'an4', 'an5', 'an6', 'an7'],
  143. swiperIndex: 0,
  144. shakeIndex: 0,
  145. pageNum: 1,
  146. shake: 0,
  147. }
  148. },
  149. watch: {
  150. kemu(val) {
  151. uni.setStorageSync('kemu', val)
  152. this.pageNum = 1
  153. this.listInit()
  154. }
  155. },
  156. mounted() {
  157. this.listInit()
  158. },
  159. methods: {
  160. async listInit() {
  161. this.loading=true
  162. await questionListRandom({
  163. num: 20,
  164. kemu: this.kemu
  165. }).then((res) => {
  166. this.questionList = res.rows
  167. this.$nextTick(() => {
  168. this.loading = false
  169. })
  170. })
  171. },
  172. questionType(index) {
  173. switch (index) {
  174. case 1:
  175. return '判断';
  176. case 2:
  177. return '单选';
  178. case 3:
  179. return '多选';
  180. }
  181. },
  182. markQuestion(id){
  183. questionErrorAdd(id).then((res)=>{
  184. })
  185. },
  186. swiperChange(e) {
  187. let aShake = e.detail.current - this.shakeIndex
  188. this.shake += aShake ** 2 != 1 ? -aShake / Math.abs(aShake) : aShake;
  189. this.swiperIndex = e.detail.current
  190. this.shakeIndex = e.detail.current
  191. if (e.detail.current % 10 == 0) {
  192. if (Math.abs(this.shake) < 10) {
  193. this.shake = 0
  194. return
  195. }
  196. this.pageNum += 1;
  197. questionListRandom({
  198. num: 10,
  199. kemu: this.kemu
  200. }).then((res) => {
  201. this.shake = 0
  202. if (e.detail.current == 20) {
  203. this.questionList = res.rows.concat(this.questionList.slice(10))
  204. }
  205. if (e.detail.current == 10) {
  206. this.questionList = this.questionList.slice(0, 20).concat(res.rows)
  207. }
  208. if (e.detail.current == 0) {
  209. this.questionList = this.questionList.slice(0, 10).concat(res.rows).concat(this.questionList.slice(20))
  210. }
  211. })
  212. }
  213. },
  214. onChange(event, itembox) {
  215. if (this.completeAnswer[itembox.id] || this.answerflag) {
  216. return
  217. }
  218. this.$set(this.userAnswer, itembox.id, event.detail)
  219. },
  220. singleToggle(event, itembox) {
  221. if (this.completeAnswer[itembox.id] || this.answerflag) {
  222. return
  223. }
  224. const {
  225. index
  226. } = event.currentTarget.dataset;
  227. this.$set(this.userAnswer, itembox.id, index)
  228. setTimeout(() => {
  229. this.submit(itembox)
  230. }, 0)
  231. },
  232. toggle(event, itembox) {
  233. const {
  234. index
  235. } = event.currentTarget.dataset;
  236. const checkbox = this.$refs[`checkboxes${itembox.id}`][index];
  237. checkbox.toggle();
  238. },
  239. noop() {},
  240. submit(itembox) {
  241. this.$set(this.completeAnswer, itembox.id, true)
  242. let flag = (this.userAnswer[itembox.id] + '').split(',').sort().join('') == itembox.answerTrue.split('').sort().join(
  243. '')
  244. if (flag) {
  245. wx.vibrateShort();
  246. if (this.answerjump) {
  247. let index = this.swiperIndex
  248. this.swiperIndex = ++index % 30
  249. }
  250. } else {
  251. wx.vibrateLong();
  252. }
  253. },
  254. changeSwitch(e) {
  255. if (e) {
  256. this.kemu = 1
  257. } else {
  258. this.kemu = 4
  259. }
  260. }
  261. }
  262. }
  263. </script>
  264. <style lang="scss" scoped>
  265. /deep/ .answer .van-cell {
  266. background-color: #16CC16 !important;
  267. color: #ffffff;
  268. }
  269. /deep/ .van-cell {
  270. // background-color: #16CC16 !important;
  271. margin: 10rpx;
  272. border-radius: 20rpx;
  273. }
  274. .content {
  275. width: 100%;
  276. height: 100vh;
  277. background-color: #FFFFFF;
  278. }
  279. .skeleton {
  280. // margin: 0rpx 20rpx;
  281. }
  282. .swiper-box {
  283. height: calc(100vh - 120rpx);
  284. margin: 0rpx 20rpx;
  285. swiper-item {
  286. overflow: auto;
  287. }
  288. }
  289. .top-box {
  290. height: 60rpx;
  291. padding: 30rpx;
  292. display: flex;
  293. justify-content: space-between;
  294. align-items: center;
  295. .icon {
  296. width: 60rpx;
  297. }
  298. .btn {}
  299. .set {
  300. color: red;
  301. }
  302. }
  303. .topic-box {
  304. // padding: 20rpx;
  305. display: flex;
  306. justify-content: center;
  307. // border: 2px solid red;
  308. .topic-top {
  309. display: flex;
  310. // border: 2px solid red;
  311. padding: 10rpx;
  312. .topic-left {
  313. display: flex;
  314. flex-direction: column;
  315. .topic-type {
  316. background: #E31818;
  317. border-radius: 10rpx;
  318. // border: 2px solid red;
  319. color: #FFFFFF;
  320. width: 66rpx;
  321. height: 30rpx;
  322. display: flex;
  323. justify-content: center;
  324. align-items: center;
  325. border-radius: 15px 15px 0px 15px;
  326. padding: 10rpx;
  327. margin-bottom: 18rpx;
  328. }
  329. }
  330. .topic-tit {
  331. padding: 10rpx;
  332. }
  333. }
  334. .topic-right {
  335. flex: 1;
  336. display: flex;
  337. flex-direction: column;
  338. padding: 0 10rpx;
  339. .topic-img {
  340. padding: 10rpx;
  341. margin: auto;
  342. width: 500rpx;
  343. height: 250rpx;
  344. // border: 2px solid red;
  345. }
  346. .topic-opt {
  347. // border: 2px solid red;
  348. padding: 30rpx 5rpx;
  349. .submit {
  350. margin: auto;
  351. margin-top: 150rpx;
  352. height: 80rpx;
  353. background: linear-gradient(90deg, #E31818, #ED3E24, #ED4F24);
  354. border-radius: 35rpx;
  355. display: flex;
  356. justify-content: center;
  357. align-items: center;
  358. color: #FFFFFF;
  359. }
  360. }
  361. }
  362. }
  363. .flag {
  364. // border: 2px solid red;
  365. padding: 30rpx 5rpx;
  366. display: flex;
  367. justify-content: center;
  368. .result {
  369. display: inline-block;
  370. background-color: #16CC16;
  371. // border: 2px solid red;
  372. width: 690rpx;
  373. // height: 70rpx;
  374. padding: 20rpx;
  375. display: flex;
  376. align-items: center;
  377. justify-content: center;
  378. border-radius: 20rpx;
  379. color: #ffffff;
  380. }
  381. }
  382. .item-titBox {
  383. display: flex;
  384. justify-content: space-between;
  385. align-items: center;
  386. padding: 20rpx;
  387. border-bottom: 1rpx solid #e8e8e8;
  388. .item-tit {
  389. border-left: 8rpx solid #E31818;
  390. font-size: 30rpx;
  391. // line-height: 38rpx;
  392. padding: 0 11rpx;
  393. }
  394. }
  395. .parsing-text {
  396. padding: 30rpx;
  397. // border: 2px solid red;
  398. }
  399. </style>