page-exam.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. <template>
  2. <div class="page-exam-box">
  3. <div class="exam-list" v-if="examList.length > 0" id="examBox" @scroll="scrollExamBox($event)">
  4. <div
  5. class="exam-item"
  6. v-for="(item, index) in examList"
  7. :key="index"
  8. @click="handleClickExamItemFun(item)"
  9. >
  10. <div class="exam-item-title-row">
  11. <div class="exam-item-name">{{ item.name }}</div>
  12. <div
  13. :class="{
  14. 'exam-item-states': true,
  15. 'exam-item-states-gray':
  16. item.examStatus === examStatesType.NOT_START,
  17. 'exam-item-states-green':
  18. item.examStatus === examStatesType.STARTED,
  19. 'exam-item-states-red':
  20. item.examStatus === examStatesType.EXAMOVER ||
  21. item.examStatus === examStatesType.NOTEXAM,
  22. }"
  23. >
  24. {{ item.examStatusTxt }}
  25. </div>
  26. </div>
  27. <div class="exam-item-describe">
  28. 考试时间:{{ formateDateTimeFun(item.startTime) || item.startTime }}
  29. </div>
  30. <div class="exam-item-describe">
  31. 考试时长:{{ item.examTimeMinsTxt }}
  32. </div>
  33. <div class="exam-item-describe">
  34. 考试描述:<span>{{ item.description }}</span>
  35. </div>
  36. </div>
  37. </div>
  38. <div v-else class="exam-list exam-question-card">
  39. <div v-if="isInited" class="exam-question-card-nodata">暂无数据</div>
  40. <div v-else class="exam-question-card-nodata exam-question-card-loading">
  41. 加载中...
  42. </div>
  43. </div>
  44. </div>
  45. </template>
  46. <script>
  47. import { Toast } from "vant";
  48. import { mapState } from "vuex";
  49. export default {
  50. name: "page-exam",
  51. components: {},
  52. data() {
  53. return {
  54. examStatesType: {
  55. NOT_START: 0, // 未开考
  56. STARTED: 1, // 已开考
  57. STARTEXAMING: 2, // 考试中
  58. EXAMOVER: 3, // 已考完
  59. NOTEXAM: 4 // 未参考
  60. },
  61. examList: [],
  62. isInited: false, // 是否已加载完毕
  63. examPage: 0,
  64. examSize: 10,
  65. canExamFlag: true // 加载考试标志
  66. };
  67. },
  68. computed: {
  69. ...mapState({
  70. exam: state => state.exam,
  71. chooseEngneeringWork: state => state.user.chooseEngneeringWork
  72. })
  73. },
  74. watch: {
  75. // 监听:工种
  76. chooseEngneeringWork(value) {
  77. console.log(value.value);
  78. if (value.value) {
  79. this.getExamListFun(); // 查询:考试的场次列表信息
  80. }
  81. }
  82. },
  83. created() {
  84. this.getExamListFun(); // 查询:考试的场次列表信息
  85. },
  86. mounted() {
  87. },
  88. destroyed () {
  89. },
  90. methods: {
  91. scrollExamBox(e) {
  92. if (this.canExamFlag && e.srcElement.scrollTop + e.srcElement.offsetHeight > e.srcElement.scrollHeight - 100) {
  93. this.canExamFlag = false;
  94. console.log("触底");
  95. this.examPage = this.examPage + 1;
  96. this.getExamListFun();
  97. }
  98. },
  99. // 查询:考试场次的列表信息
  100. getExamListFun() {
  101. this.isInited = false;
  102. this.$store.commit("toggleLoading", true);
  103. let params = {
  104. // engineertypeid: this.chooseEngneeringWork.id,
  105. page: this.examPage,
  106. size: this.examSize
  107. };
  108. this.$_http
  109. .get(this.$_API.GET_JTXT_GET_EXAMS, { params })
  110. .then(res => {
  111. // console.log("--exams--" + JSON.stringify(res));
  112. if (res.data) {
  113. res.data.content.forEach(item => {
  114. let formateTimeDiff = this.formateTimeDiffFun(item.duration);
  115. item.examTimeMins = formateTimeDiff.examTimeMins;
  116. item.examTimeMinsTxt = formateTimeDiff.examTimeMinsTxt;
  117. let obj = this.formateExamStatesFun(item);
  118. item.examStatus = obj.status;
  119. item.examStatusTxt = obj.statusTxt;
  120. });
  121. // 分页到底了
  122. if (res.data.last) {
  123. this.canExamFlag = false;
  124. } else {
  125. this.canExamFlag = true;
  126. }
  127. this.$nextTick(() => {
  128. this.examList = [...this.examList, ...res.data.content];
  129. });
  130. this.isInited = true;
  131. }
  132. this.$store.commit("toggleLoading", false);
  133. })
  134. .catch(() => {
  135. this.canExamFlag = false;
  136. Toast("系统异常");
  137. this.$store.commit("toggleLoading", false);
  138. });
  139. },
  140. formateTimeDiffFun(secondes) {
  141. let hours = Math.floor(secondes / (1000 * 60 * 60));
  142. let minutes = Math.floor(
  143. (secondes - hours * 60 * 60 * 1000) / (1000 * 60)
  144. );
  145. let seconds = Math.floor(
  146. (secondes - hours * 60 * 60 * 1000 - minutes * 60 * 1000) / 1000
  147. );
  148. let timeDiff = zero(hours) + ":" + zero(minutes) + ":" + zero(seconds);
  149. let timeDiffTxt =
  150. zero(hours) + "小时" + zero(minutes) + "分钟" + zero(seconds) + "秒";
  151. // 数字补零
  152. function zero(num) {
  153. return num < 10 ? "0" + num : num;
  154. }
  155. return {
  156. examTimeMins: timeDiff,
  157. examTimeMinsTxt: timeDiffTxt
  158. };
  159. },
  160. // 过滤考试状态
  161. formateExamStatesFun(exam) {
  162. let startTime = exam.startTime;
  163. let endTime = exam.deadline;
  164. let curTime = Date.now();
  165. let startTimesCeconds = new Date(startTime).getTime();
  166. let endTimeCeconds = new Date(endTime).getTime();
  167. if (curTime >= startTimesCeconds) {
  168. if (curTime >= endTimeCeconds) {
  169. if (this.exam.examHistoryObj && this.exam.examHistoryObj[exam.id]) {
  170. return {
  171. status: this.examStatesType.EXAMOVER,
  172. statusTxt: "已考完"
  173. };
  174. } else {
  175. return {
  176. status: this.examStatesType.NOTEXAM,
  177. statusTxt: "未参考"
  178. };
  179. }
  180. } else {
  181. return {
  182. status: this.examStatesType.STARTED,
  183. statusTxt: "已开考"
  184. };
  185. }
  186. } else {
  187. return {
  188. status: this.examStatesType.NOT_START,
  189. statusTxt: "未开考"
  190. };
  191. }
  192. },
  193. // 操作:点击了某个考试
  194. handleClickExamItemFun(item) {
  195. let isCouldExam = false;
  196. switch (item.examStatus) {
  197. case this.examStatesType.NOT_START:
  198. Toast("考试未开考");
  199. break;
  200. case this.examStatesType.EXAMOVER:
  201. Toast("已考完");
  202. break;
  203. case this.examStatesType.STARTED:
  204. isCouldExam = true;
  205. break;
  206. case this.examStatesType.STARTEXAMING:
  207. case this.examStatesType.NOTEXAM:
  208. Toast("考试已结束");
  209. break;
  210. default:
  211. break;
  212. }
  213. if (!isCouldExam) {
  214. return;
  215. }
  216. this.$store.commit("updateExamItemStore", {
  217. field: "examItem",
  218. value: item
  219. });
  220. this.$router.push({ name: "ExamDetail" });
  221. }
  222. }
  223. };
  224. </script>
  225. <style lang="scss" scoped>
  226. @import "~@/styles/mixin";
  227. .page-exam-box {
  228. width: 100%;
  229. height: 100%;
  230. // overflow-y: auto;
  231. // overflow-x: hidden;
  232. font-size: 0.6rem;
  233. .exam-list {
  234. height: 100vh;
  235. overflow-y: scroll;
  236. padding: 0.5rem 0.5rem;
  237. .exam-item {
  238. width: 100%;
  239. padding: 0 0.5rem 0.5rem;
  240. margin-bottom: 0.7rem;
  241. background-color: #fff;
  242. border-radius: 4px;
  243. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
  244. .exam-item-title-row {
  245. width: 100%;
  246. display: flex;
  247. justify-content: space-between;
  248. align-items: center;
  249. border-bottom: 1px solid #e4e8eb;
  250. .exam-item-name {
  251. padding: 0.5rem 0 0.25rem;
  252. font-size: 0.65rem;
  253. font-weight: bold;
  254. color: #000;
  255. word-break: break-all;
  256. word-wrap: break-word;
  257. }
  258. .exam-item-states {
  259. font-size: 0.6rem;
  260. border-radius: 0.2rem;
  261. margin-left: 1rem;
  262. flex-wrap: nowrap;
  263. white-space: nowrap;
  264. }
  265. }
  266. .exam-item-states-yellow {
  267. color: #e6a23c;
  268. }
  269. .exam-item-states-green {
  270. color: #67c23a;
  271. }
  272. .exam-item-states-red {
  273. color: #f56c6c;
  274. }
  275. .exam-item-states-gray {
  276. color: #909399;
  277. }
  278. .exam-item-describe {
  279. margin-top: 0.5rem;
  280. span {
  281. letter-spacing: 0.2rem;
  282. }
  283. }
  284. }
  285. }
  286. .exam-question-card-loading,
  287. .exam-question-card-nodata {
  288. width: 100%;
  289. height: 5rem;
  290. color: #333;
  291. font-size: 0.7rem;
  292. display: flex;
  293. justify-content: center;
  294. align-items: center;
  295. }
  296. }
  297. </style>