trainDetail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. <template>
  2. <div class="trainDetail">
  3. <van-sticky>
  4. <m-header v-if="headerStatus" :isFixed="false" />
  5. </van-sticky>
  6. <div class="evaluation">
  7. <van-cell style="padding: 16px 12px; background-color: transparent" :center="true">
  8. <template #title>
  9. <div class="teacher_info">
  10. <img class="logo" v-if="avatar" :src="avatar" alt="" />
  11. <img class="logo" v-else src="../../assets/images/icon_student.png" alt="" />
  12. <div class="teacher_content">
  13. <p style="color: #1a1a1a; font-size: .18rem;">{{ username }}</p>
  14. <p style="font-size: 14px; color: #333;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width: 2.4rem;">{{ musicGroupName }}</p>
  15. </div>
  16. </div>
  17. </template>
  18. <!-- <p style="font-size: 14px; color: #808080;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">{{ musicGroupName }}</p> -->
  19. </van-cell>
  20. </div>
  21. <van-row class="dataSearch" type="flex">
  22. <van-col span="9" offset="1">
  23. <van-cell @click="onChangeDate('showStart')" is-link>
  24. <template #right-icon>
  25. <van-icon :name="arrowIcon" class="search-icon" size="10" />
  26. </template>
  27. <template v-if="searchList.startTime">{{ searchList.startTime }}</template>
  28. <span v-else style="color: #adadad;">开始日期</span>
  29. </van-cell>
  30. </van-col>
  31. <van-col span="1" class="flexCenter">-</van-col>
  32. <van-col span="9">
  33. <van-cell @click="onChangeDate('showEnd')">
  34. <template #right-icon>
  35. <van-icon :name="arrowIcon" class="search-icon" size="10" />
  36. </template>
  37. <template v-if="searchList.endTime">{{ searchList.endTime }}</template>
  38. <span v-else style="color: #adadad;">结束日期</span>
  39. </van-cell>
  40. </van-col>
  41. <van-col span="4" class="flexCenter">
  42. <span class="btn-search" @click="onSearch">搜索</span>
  43. </van-col>
  44. </van-row>
  45. <van-popup v-model="dataForm.status" position="bottom" round :style="{ height: '40%' }">
  46. <van-datetime-picker
  47. v-model="dataForm.currentDate"
  48. :min-date="dataForm.minDate"
  49. :max-date="dataForm.maxDate"
  50. :formatter="formatter"
  51. @cancel="dataForm.status = false"
  52. type="date"
  53. @confirm="chioseDate"
  54. />
  55. </van-popup>
  56. <div class="specialList">
  57. <van-list v-model="loading" v-if="show" key="trainDetail"
  58. :finished="finished"
  59. finished-text="- 没有更多内容 -"
  60. :immediate-check="false"
  61. @load="getList()">
  62. <van-cell-group class="data-content" v-for="(item, index) in dataList" :key="index" @click="showDetail(item)">
  63. <van-cell style="padding: 16px 12px; 12px" :center="true">
  64. <template #title>
  65. <span style="font-size: .17rem; color:#333333; font-weight: 500; padding-right: .05rem;padding-bottom: .05rem;">{{ item.sysMusicScoreName }}</span>
  66. <p style="font-size: 14px; color: #808080;">{{ item.createTime }}</p>
  67. </template>
  68. <p>
  69. <img v-if="getLevelByScore(item.score) == 1" class="scoreImg" src="./images/1.png" alt="">
  70. <img v-if="getLevelByScore(item.score) == 2" class="scoreImg" src="./images/2.png" alt="">
  71. <img v-if="getLevelByScore(item.score) == 3" class="scoreImg" src="./images/3.png" alt="">
  72. </p>
  73. </van-cell>
  74. <van-cell is-link :clickable="false" center style="padding: 12px 12px 16px">
  75. <template #title>
  76. <van-grid :border="false" column-num="4" :clickable="true">
  77. <van-grid-item text="综合得分" class="van-hairline--right">
  78. <template #icon>{{ item.score }}分</template>
  79. </van-grid-item>
  80. <van-grid-item text="音准" class="van-hairline--right">
  81. <template #icon><span style="color: #01C1B5">{{ item.intonation }}分</span></template>
  82. </van-grid-item>
  83. <van-grid-item text="节奏" class="van-hairline--right">
  84. <template #icon><span style="color: #01C1B5">{{ item.cadence }}分</span></template>
  85. </van-grid-item>
  86. <van-grid-item text="完成度">
  87. <template #icon><span style="color: #FF802C">{{ item.integrity }}分</span></template>
  88. </van-grid-item>
  89. </van-grid>
  90. </template>
  91. </van-cell>
  92. </van-cell-group>
  93. </van-list>
  94. <m-empty v-else key="trainDetail" msg="暂无训练详情" />
  95. <div class="button-group">
  96. <van-button type="primary" size="large" round @click="addVisited">添加回访</van-button>
  97. <div class="placeholder-btn"></div>
  98. </div>
  99. </div>
  100. </div>
  101. </template>
  102. <script>
  103. import MHeader from "@/components/MHeader";
  104. import MEmpty from '@/components/MEmpty';
  105. import { postMessage } from "@/helpers/native-message";
  106. import dayjs from "dayjs";
  107. import { browser } from "@/common/common";
  108. import { queryMusicCompareRecord } from './api.js'
  109. export default {
  110. components: { MHeader, MEmpty },
  111. data() {
  112. const query = this.$route.query
  113. return {
  114. arrowIcon: require('./images/arrow_down.png'),
  115. headerStatus: true,
  116. show: true,
  117. avatar: query.avatar,
  118. username: query.username,
  119. musicGroupName: query.musicGroupName,
  120. searchList: {
  121. startTime: null,
  122. endTime: null,
  123. userId: query.userId,
  124. page: 1,
  125. rows: 20
  126. },
  127. dataForm: {
  128. // 时间下拉框
  129. type: null,
  130. status: false,
  131. minDate: new Date(2000, 0, 1),
  132. maxDate: new Date(2030, 11, 31),
  133. currentDate: new Date(),
  134. },
  135. dataList: [],
  136. loading: false,
  137. finished: false,
  138. }
  139. },
  140. mounted() {
  141. if (browser().android || browser().iPhone) {
  142. this.headerStatus = false;
  143. }
  144. document.title = '评测详情'
  145. this.getList()
  146. },
  147. methods: {
  148. addVisited() {
  149. this.$router.push({
  150. path: '/addVisit',
  151. query: {
  152. ...this.$route.query,
  153. type: 'train',
  154. name: '新增回访记录'
  155. }
  156. })
  157. },
  158. showDetail(item) {
  159. if(item.notesDataIndex > 0){
  160. postMessage({
  161. api: "openAccompanyWebView",
  162. content: {
  163. url: location.origin + `/accompany/#/report/${item.id}`,
  164. orientation: 0,
  165. isHideTitle: true,
  166. statusBarTextColor: false,
  167. isOpenLight: true,
  168. },
  169. });
  170. }else{
  171. this.$toast('本次评测未生成报告')
  172. }
  173. },
  174. async getList() {
  175. try {
  176. let res = await queryMusicCompareRecord(this.searchList)
  177. let result = res.data
  178. this.loading = false
  179. // 重点这句,判断是不是重复请求了
  180. if (this.dataList.length > 0 && result.pageNo == 1) {
  181. return;
  182. }
  183. let rows = result.rows || []
  184. this.dataList.push(...rows)
  185. if(this.searchList.page >= result.totalPage) {
  186. this.finished = true
  187. }
  188. this.searchList.page++
  189. if(this.dataList.length <= 0) {
  190. this.show = false
  191. }
  192. } catch {
  193. this.show = false
  194. this.finished = true
  195. }
  196. },
  197. onSearch() {
  198. this.dataList = [] // 重置数据
  199. this.show = true
  200. this.loading = true
  201. this.finished = false
  202. this.searchList.page = 1
  203. this.getList()
  204. },
  205. onChangeDate(type) {
  206. let dataForm = this.dataForm
  207. if(type == 'showEnd' && this.searchList.startTime) {
  208. dataForm.minDate = new Date(dayjs(this.searchList.startTime))
  209. dataForm.maxDate = new Date(2030, 11, 31)
  210. setTimeout(() => {
  211. dataForm.currentDate = this.searchList.endTime ? new Date(dayjs(this.searchList.endTime)) : new Date()
  212. }, 500)
  213. } else if(type == 'showStart' && this.searchList.endTime) {
  214. dataForm.minDate = new Date(2000, 0, 1)
  215. dataForm.maxDate = new Date(dayjs(this.searchList.endTime))
  216. setTimeout(() => {
  217. dataForm.currentDate = this.searchList.startTime ? new Date(dayjs(this.searchList.startTime)) : new Date()
  218. }, 500)
  219. }
  220. dataForm.status = true
  221. dataForm.type = type
  222. },
  223. chioseDate(value) {
  224. let dataForm = this.dataForm
  225. if(dataForm.type == 'showStart') {
  226. this.searchList.startTime = dayjs(value).format('YYYY-MM-DD')
  227. } else if(dataForm.type == 'showEnd') {
  228. this.searchList.endTime = dayjs(value).format('YYYY-MM-DD')
  229. }
  230. dataForm.status = false
  231. },
  232. formatter(type, val) {
  233. if (type === "year") {
  234. return `${val}年`;
  235. } else if (type === "month") {
  236. return `${val}月`;
  237. } else if (type == "day") {
  238. return `${val}日`;
  239. }
  240. return val;
  241. },
  242. getLevelByScore(score) {
  243. let level = 3
  244. if (score > 60 && score <= 80) {
  245. level = 2
  246. } else if (score > 80) {
  247. level = 1
  248. }
  249. return level
  250. }
  251. }
  252. }
  253. </script>
  254. <style lang="less" scoped>
  255. .trainDetail {
  256. background: #f5f5f5;
  257. min-height: 100vh;
  258. overflow: hidden;
  259. }
  260. .evaluation {
  261. display: flex;
  262. align-items: center;
  263. margin: .12rem .12rem 0;
  264. height: 1.05rem;
  265. border-radius: .1rem;
  266. background: url('./images/user_bg.png') no-repeat center #fff;
  267. background-size: contain;
  268. .teacher_info {
  269. display: flex;
  270. align-items: center;
  271. img {
  272. margin-right: .15rem;
  273. width: .6rem;
  274. height: .6rem;
  275. border-radius: 50%;
  276. }
  277. }
  278. }
  279. .search-icon {
  280. display: flex;
  281. align-items: center;
  282. }
  283. .scoreImg {
  284. width: 66px;
  285. height: 25px;
  286. }
  287. .data-content {
  288. margin: .15rem .15rem 0;
  289. border-radius: .1rem;
  290. overflow: hidden;
  291. &:first-child {
  292. margin-top: 0;
  293. }
  294. .van-row-item {
  295. display: flex;
  296. align-items: center;
  297. }
  298. /deep/.van-grid-item__content {
  299. padding: .03rem
  300. }
  301. /deep/.van-grid-item__content {
  302. background-color: transparent;
  303. }
  304. /deep/.van-grid-item__icon-wrapper {
  305. font-size: .15rem;
  306. color: #000;
  307. }
  308. /deep/.van-grid-item__text {
  309. font-size: .14rem;
  310. color: #808080;
  311. }
  312. .teacher_info {
  313. display: flex;
  314. align-items: center;
  315. img {
  316. margin-right: .1rem;
  317. width: .4rem;
  318. height: .4rem;
  319. border-radius: 50%;
  320. }
  321. }
  322. }
  323. .specialList {
  324. padding-top: .1rem;
  325. padding-bottom: 65px;
  326. // padding-bottom: calc(env(safe-area-inset-bottom) / 2);
  327. }
  328. .dataSearch {
  329. padding: .12rem;
  330. background-color: #F5F5F5;
  331. /deep/.van-cell {
  332. background: #fff;
  333. padding: .05rem .16rem;
  334. border-radius: 1rem;
  335. overflow: hidden;
  336. height: .34rem;
  337. }
  338. /deep/.van-cell__value--alone {
  339. text-align: center;
  340. }
  341. .flexCenter {
  342. display: flex;
  343. align-items: center;
  344. justify-content: center;
  345. }
  346. .btn-search {
  347. background: #01C1B5;
  348. font-size: 14px;
  349. color: #fff;
  350. padding: 4px 9px;
  351. border-radius: 15px;
  352. }
  353. }
  354. .button-group {
  355. overflow: hidden;
  356. position: fixed;
  357. bottom: 0;
  358. width: calc(100% - .24rem);
  359. z-index: 9;
  360. margin: 0 .12rem 12px;
  361. .van-button--primary {
  362. background: #01C1B5;
  363. border: 1px solid #01C1B5;
  364. font-size: .16rem;
  365. float: right;
  366. // padding-bottom: calc(env(safe-area-inset-bottom) / 2);
  367. height: auto;
  368. line-height: 48px;
  369. }
  370. }
  371. </style>