select.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <template>
  2. <view class="container-box">
  3. <image src="/static/image/bmi/manual_icon_arrow.png" alt="" class="back-class" @click="goBcak()"></image>
  4. <text class="countdown">倒计时{{ countdown }}s</text>
  5. <view class="select-box">
  6. <view class="select-tab">
  7. <view v-for="(item, index) in tabs" :key="index" class="tab-item"
  8. :class="item.type == activeTab ? `tab-active-item${index}` : `tab-item${index}`" @click="changeTab(item)">
  9. <image class="tab-img" :src="item.type == activeTab ? item.actImg : item.img" alt=""></image>
  10. <text>{{ item.title }}</text>
  11. </view>
  12. </view>
  13. <view class="select-info" v-if="activeTab == 'grade'">
  14. <view v-for="(item, index) in totalList" class="info-item" @click="changeGrade(item)"
  15. :class="item.active == true ? `info-active-item0` : `info-item0`">{{ item.name }}</view>
  16. </view>
  17. <view class="select-info" v-else-if="activeTab == 'class'">
  18. <view v-for="(item, index) in classList" class="info-item" @click="changeClass(item)"
  19. :class="item.active == true ? `info-active-item1` : `info-item1`">{{ item.class_name }}</view>
  20. </view>
  21. <view class="select-info" v-else-if="activeTab == 'student'">
  22. <view v-for="(item, index) in studentList" class="info-item" @click="changeStudent(item)"
  23. :class="item.active == true ? `info-active-item2` : `info-item2`">{{ item.jname }}</view>
  24. </view>
  25. </view>
  26. <view class="selected-box">
  27. <view>已选择:</view>
  28. <view class="selected-info">
  29. <view v-for="(item, index) in curSelected" :key="index">
  30. <text v-if="index != 0" class="selected-line">|</text>
  31. <text>{{ item.name }}</text>
  32. </view>
  33. </view>
  34. </view>
  35. <view :class="curSelected.length == 3 ? 'next-btn' : 'ban-btn'" @click="navToTest">进入检测页</view>
  36. </view>
  37. </template>
  38. <script setup>
  39. import { onActivated, onUnmounted, watch, ref, computed } from "vue";
  40. import { onLoad, onUnload, onHide } from '@dcloudio/uni-app';
  41. import { navTo, showToast } from "@/utils/app";
  42. import { getTaskClassList, getTaskStudentList } from "@/api/student";
  43. const title = ref('学生未激活')
  44. const select = ref(0)
  45. const selectMax = ref(1)
  46. const totalList = ref([])
  47. const activeTab = ref('grade')
  48. const countdown = ref(5)
  49. const interval = ref()
  50. const queryForm = ref({
  51. student_id: 0,
  52. })
  53. const tabs = ref([
  54. { title: '选择年级', type: 'grade', img: '/static/image/bmi/manual_icon_grade.png', actImg: '/static/image/bmi/manual_icon_grade_selected.png' },
  55. { title: '选择班级', type: 'class', img: '/static/image/bmi/manual_icon_class.png', actImg: '/static/image/bmi/manual_icon_class_selected.png' },
  56. { title: '选择学生', type: 'student', img: '/static/image/bmi/manual_icon_student.png', actImg: '/static/image/bmi/manual_icon_student_selected.png' }
  57. ])
  58. const selectedArr = ref([
  59. { name: '三年级', id: 1 },
  60. { name: '1班', id: 2 },
  61. { name: '11', id: 3 },
  62. ])
  63. const setCountdown = ()=>{
  64. interval.value = setInterval(()=>{
  65. countdown.value -=1
  66. } , 1000);
  67. if(countdown.value == 0){
  68. clearInterval(interval)
  69. goBcak()
  70. }
  71. }
  72. watch(countdown, (newVal, oldVal)=>{
  73. if(newVal <= 0){
  74. clearInterval(interval.value)
  75. goBcak()
  76. }
  77. })
  78. const classList = computed(() => {
  79. let activeGrade = totalList.value.find(item => item.active == true)
  80. return activeGrade ? activeGrade.class : null
  81. })
  82. const studentList = computed(() => {
  83. let activeGrade = totalList.value.find(item => item.active == true)
  84. if (activeGrade && activeGrade.class) {
  85. let activeClass = activeGrade.class.find(item => item.active == true)
  86. return activeClass ? activeClass.student : null
  87. }
  88. return null
  89. })
  90. const curSelected = computed(() => {
  91. let arr = []
  92. let activeGrade = totalList.value.find(item => item.active == true)
  93. if (activeGrade) {
  94. arr.push(activeGrade)
  95. let activeClass = classList.value.find(item => item.active == true)
  96. if (activeClass) {
  97. arr.push(activeClass)
  98. if(studentList.value && studentList.value.length > 0){
  99. let activeStudent = studentList.value.find(item => item.active == true)
  100. if (activeStudent) arr.push(activeStudent)
  101. }
  102. }
  103. }
  104. return arr
  105. })
  106. const getGradeList = async () => {
  107. const res = await getTaskClassList()
  108. const list = []
  109. if(res.code == 1){
  110. res.data.grades.forEach(el => {
  111. if (!list.some(e => e.id == el.id)) {
  112. list.push(el);
  113. }
  114. });
  115. }
  116. totalList.value = list
  117. const classList = []
  118. for(let item of res.data.list){
  119. for(let task of item.task){
  120. classList.push({
  121. ...item,
  122. ...task,
  123. name: item.class_name
  124. })
  125. }
  126. }
  127. for(let gradeItem of totalList.value){
  128. let arr = []
  129. for(let classItem of classList){
  130. if(gradeItem.id == classItem.grade){
  131. arr.push(classItem)
  132. }
  133. }
  134. if(arr.length > 0)gradeItem.class = arr
  135. }
  136. }
  137. const getStudent = async (item) => {
  138. const res = await getTaskStudentList({
  139. task_id: item.task_id
  140. })
  141. if(res.code == 1){
  142. let list = res.data.list.map(i=>{
  143. return {...i,name: i.jname}
  144. })
  145. totalList.value.find(item => item.active == true).class
  146. .find(item => item.active == true).student = list
  147. }
  148. }
  149. const changeTab = (item) => {
  150. activeTab.value = item.type
  151. }
  152. const changeGrade = (item) => {
  153. activeTab.value = 'class'
  154. for (let i of totalList.value) { i.active = false }
  155. item.active = true
  156. let classList = totalList.value.find(i => i.active == true).class
  157. for (let i of classList) { i.active = false }
  158. // getClassList()
  159. }
  160. const changeClass = (item) => {
  161. activeTab.value = 'student'
  162. let classList = totalList.value.find(i => i.active == true).class
  163. for (let i of classList) { i.active = false }
  164. item.active = true
  165. getStudent(item)
  166. }
  167. const changeStudent = (item) => {
  168. let classList = totalList.value.find(i => i.active == true).class
  169. let studentList = classList.find(i => i.active == true).student
  170. for (let i of studentList) { i.active = false }
  171. item.active = true
  172. }
  173. const goBcak = () => {
  174. navTo('pages/index/index', {
  175. })
  176. }
  177. const navToTest = () => {
  178. if (curSelected.value.length == 3) {
  179. navTo('pages/test/bmi', {
  180. student_id: curSelected.value[2].id,
  181. task_id: curSelected.value[1].task_id,
  182. })
  183. }
  184. }
  185. onLoad(() => {
  186. getGradeList()
  187. setCountdown()
  188. })
  189. onHide(()=>{
  190. clearInterval(interval.value)
  191. })
  192. onUnload(()=>{
  193. clearInterval(interval.value)
  194. })
  195. </script>
  196. <style scoped>
  197. .container-box {
  198. height: 100vh;
  199. width: 100%;
  200. background: linear-gradient(to bottom left, rgb(218, 233, 253), #fff, rgb(218, 233, 253));
  201. position: relative;
  202. overflow: auto;
  203. }
  204. .back-class {
  205. position: absolute;
  206. top: 40upx;
  207. left: 46upx;
  208. width: 70upx;
  209. height: 70upx;
  210. }
  211. .countdown {
  212. position: absolute;
  213. top: 40upx;
  214. right: 46upx;
  215. font-weight: bold;
  216. font-size: 35upx;
  217. color: #2F3C42;
  218. line-height: 41upx;
  219. }
  220. .select-box {
  221. margin: 125upx auto 0;
  222. width: 680upx;
  223. height: 55vh;
  224. border-radius: 14upx;
  225. background: #fff;
  226. box-shadow: 0 0px 5px 1px #ccc;
  227. }
  228. .selected-box {
  229. margin: 25upx auto 0;
  230. width: 680upx;
  231. height: 15vh;
  232. line-height: 6vh;
  233. border-radius: 14upx;
  234. background: #fff;
  235. box-shadow: 0 0px 5px 1px #ccc;
  236. font-weight: bold;
  237. font-size: 28rpx;
  238. padding: 1.5vh 27upx;
  239. box-sizing: border-box;
  240. color: #0369E8;
  241. }
  242. .selected-info {
  243. display: flex;
  244. font-weight: 400;
  245. font-size: 28rpx;
  246. color: #2F3C42;
  247. }
  248. .selected-line {
  249. color: #ccc;
  250. padding: 0 10upx;
  251. }
  252. .next-btn {
  253. margin: 25upx auto 0;
  254. width: 389upx;
  255. height: 9vh;
  256. line-height: 9vh;
  257. border-radius: 14upx;
  258. background: #0369E8;
  259. color: #fff;
  260. font-weight: bold;
  261. font-size: 35rpx;
  262. text-align: center;
  263. }
  264. .ban-btn {
  265. margin: 25upx auto 0;
  266. width: 389upx;
  267. height: 9vh;
  268. line-height: 9vh;
  269. border-radius: 14upx;
  270. background: #ccc;
  271. color: #666;
  272. font-weight: bold;
  273. font-size: 35rpx;
  274. text-align: center;
  275. }
  276. .select-tab {
  277. display: flex;
  278. border-bottom: 1px solid #ccc;
  279. }
  280. .tab-img {
  281. width: 42upx;
  282. height: 42upx;
  283. margin-top: 34upx;
  284. }
  285. .tab-item {
  286. flex: 1;
  287. display: flex;
  288. justify-content: center;
  289. text-align: center;
  290. height: 10vh;
  291. line-height: 110upx;
  292. font-weight: bold;
  293. font-size: 28rpx;
  294. border-top-left-radius: 14upx;
  295. border-top-right-radius: 14upx;
  296. }
  297. .tab-item0 {
  298. color: rgb(3, 105, 232);
  299. background: #fff;
  300. }
  301. .tab-item1 {
  302. color: rgb(2, 193, 124);
  303. background: #fff;
  304. }
  305. .tab-item2 {
  306. color: rgb(211, 121, 13);
  307. background: #fff;
  308. }
  309. .tab-active-item0 {
  310. background: rgb(3, 105, 232);
  311. color: #fff;
  312. }
  313. .tab-active-item1 {
  314. background: rgb(2, 193, 124);
  315. color: #fff;
  316. }
  317. .tab-active-item2 {
  318. background: rgb(211, 121, 13);
  319. color: #fff;
  320. }
  321. .select-info {
  322. padding: 20upx 10upx 20upx 20upx;
  323. display: flex;
  324. flex-wrap: wrap;
  325. height: 40vh;
  326. overflow: auto;
  327. }
  328. .info-item {
  329. height: 69upx;
  330. width: 139upx;
  331. border-radius: 10upx;
  332. font-weight: bold;
  333. font-size: 21upx;
  334. text-align: center;
  335. line-height: 69upx;
  336. margin-right: 18upx;
  337. margin-bottom: 18upx;
  338. }
  339. .info-item0 {
  340. background: #F1F7FF;
  341. color: #0369E8;
  342. }
  343. .info-active-item0 {
  344. color: #fff;
  345. background: #0369E8;
  346. }
  347. .info-item1 {
  348. background: #EFFFF8;
  349. color: rgb(2, 193, 124);
  350. }
  351. .info-active-item1 {
  352. color: #EFFFF8;
  353. background: rgb(2, 193, 124);
  354. }
  355. .info-item2 {
  356. background: #FFFCF5;
  357. color: #D3790D;
  358. }
  359. .info-active-item2 {
  360. color: #FFFCF5;
  361. background: #D3790D;
  362. }
  363. </style>