cloudTextbooks.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <!--
  2. * @FileDescription: 云课堂
  3. * @Author: 黄琪勇
  4. * @Date:2024-03-21 15:11:49
  5. -->
  6. <template>
  7. <navContainer :navs="navs">
  8. <div class="cloudTextbooks">
  9. <div class="headCon">
  10. <div class="operate">
  11. <dictionary
  12. :popper-class="'classTypePopper'"
  13. v-model="classType"
  14. :width="150"
  15. :height="40"
  16. :options="classTypeOpt"
  17. placeholder="课程类型"
  18. @change="handleQuery"
  19. />
  20. <myInput
  21. class="queryIpt"
  22. v-model="queryStr"
  23. :width="382"
  24. :height="40"
  25. placeholder="请输入教材名称"
  26. @keyup.enter="handleQuery"
  27. @input="handleInputQuery"
  28. @handleQuery="handleQuery"
  29. clearable
  30. />
  31. </div>
  32. </div>
  33. <div class="cloudTextbooksCon">
  34. <ElScrollbar class="elScrollbar" v-loading="loading">
  35. <div class="cloudTextbooksBox">
  36. <div class="bookshelf" v-for="(list, index) in listData" :key="index">
  37. <div class="book" v-for="item in list" :key="item.id">
  38. <div class="imgCon" @click="handleClick(item.id)">
  39. <ElImage class="img" :src="item.img" />
  40. <img class="imgbg" src="@/img/cloudTextbooks/yy.png" />
  41. <img class="imgbg1" src="@/img/cloudTextbooks/hd1.png" />
  42. <img class="imgbg2" src="@/img/cloudTextbooks/hd.png" />
  43. <div class="courseNum">共{{ item.courseNum }}课</div>
  44. </div>
  45. <div class="name">{{ item.name }}</div>
  46. </div>
  47. </div>
  48. </div>
  49. </ElScrollbar>
  50. </div>
  51. <el-empty class="empty" v-if="!listData.length && !loading" :image="require('@/img/layout/empty.png')" description="暂无搜索结果" />
  52. </div>
  53. </navContainer>
  54. </template>
  55. <script setup lang="ts">
  56. import navContainer from "@/businessComponents/navContainer"
  57. import { ref, shallowRef } from "vue"
  58. import modalFrame from "@/plugin/modalFrame"
  59. import chooseDialog from "./chooseDialog.vue"
  60. import userStore from "@/store/modules/user"
  61. import { useDataList } from "./useData"
  62. import { debounce } from "@/libs/tools"
  63. import { getLessonCoursewareSubjectList_gym } from "@/api/cloudTextbooks.api"
  64. import { httpAjax } from "@/plugin/httpAjax"
  65. import myInput from "@/components/myInput"
  66. const userStoreHook = userStore()
  67. const { handleGetList, listData, loading, handleListQuery } = useDataList()
  68. const navs = [
  69. {
  70. name: "主页",
  71. url: "/"
  72. },
  73. {
  74. name: "云课堂"
  75. }
  76. ]
  77. const classType = ref("")
  78. const classTypeOpt = shallowRef<{ value: string; label: string }[]>([])
  79. const queryStr = ref("")
  80. handleGetClassTypeOpt()
  81. handleGetList()
  82. enum courseEmnu {
  83. PERCUSSION_SINGLE = "打击乐",
  84. FLUTE_SINGLE = "长笛",
  85. SAX_SINGLE = "萨克斯",
  86. CLARINET_SINGLE = "单簧管",
  87. TRUMPET_SINGLE = "小号",
  88. TROMBONE_SINGLE = "长号",
  89. HORN_SINGLE = "圆号",
  90. BARITONE_TUBA_SINGLE = "上低音号-大号",
  91. MUSIC_THEORY = "乐理",
  92. INSTRUMENTAL_ENSEMBLE = "合奏",
  93. EUPHONIUM_SINGLE = "上低音号",
  94. TUBA_SINGLE = "大号"
  95. }
  96. function handleGetClassTypeOpt() {
  97. // 区分管乐团和管乐迷课程类型
  98. if (userStoreHook.roles === "GYM") {
  99. httpAjax(getLessonCoursewareSubjectList_gym).then(res => {
  100. if (res.code === 200) {
  101. classTypeOpt.value = [
  102. {
  103. value: "",
  104. label: "全部"
  105. },
  106. ...res.data.map((item: any) => {
  107. return {
  108. value: item.id,
  109. label: item.name
  110. }
  111. })
  112. ]
  113. }
  114. })
  115. } else {
  116. classTypeOpt.value = [
  117. {
  118. value: "",
  119. label: "全部"
  120. },
  121. ...Object.keys(courseEmnu).map(type => {
  122. return {
  123. value: type,
  124. label: courseEmnu[type as keyof typeof courseEmnu]
  125. }
  126. })
  127. ]
  128. }
  129. }
  130. // 查询
  131. function handleQuery() {
  132. handleListQuery(classType.value, queryStr.value)
  133. }
  134. const handleInputQuery = debounce(handleQuery)
  135. //点击跳转详情
  136. function handleClick(id: string) {
  137. modalFrame({
  138. template: chooseDialog,
  139. width: 1152,
  140. height: 700,
  141. btnShow: [],
  142. modalData: {
  143. id
  144. },
  145. maskClose: true,
  146. className: "chooseDialog"
  147. })
  148. }
  149. </script>
  150. <style lang="scss" scoped>
  151. .cloudTextbooks {
  152. width: 100%;
  153. height: 100%;
  154. position: relative;
  155. .headCon {
  156. padding: 30px 26px;
  157. display: flex;
  158. flex-direction: row-reverse;
  159. .operate {
  160. display: flex;
  161. .queryIpt {
  162. margin-left: 12px;
  163. }
  164. }
  165. }
  166. .cloudTextbooksCon {
  167. height: calc(100% - 122px);
  168. > :deep(.elScrollbar) {
  169. .el-scrollbar__wrap {
  170. overflow-x: hidden;
  171. }
  172. }
  173. .cloudTextbooksBox {
  174. display: flex;
  175. flex-direction: column;
  176. align-items: center;
  177. padding-top: 10px;
  178. .bookshelf {
  179. width: 1500px;
  180. padding: 0 116px;
  181. margin-bottom: 70px;
  182. display: flex;
  183. flex-wrap: wrap;
  184. background: url("@/img/cloudTextbooks/sj.png") no-repeat;
  185. background-size: contain;
  186. background-position-y: 120px;
  187. &:last-child {
  188. margin-bottom: 0;
  189. }
  190. .book {
  191. width: 20%;
  192. text-align: center;
  193. position: relative;
  194. padding-top: 4px;
  195. .imgCon {
  196. width: 172px;
  197. height: 212px;
  198. display: inline-block;
  199. position: relative;
  200. cursor: pointer;
  201. &:hover {
  202. transform: translateY(-4px);
  203. }
  204. .img {
  205. width: 172px;
  206. height: 212px;
  207. }
  208. .imgbg {
  209. position: absolute;
  210. top: -20px;
  211. right: -50px;
  212. width: 76px;
  213. height: 247px;
  214. pointer-events: none;
  215. }
  216. .imgbg1 {
  217. position: absolute;
  218. top: 0px;
  219. right: -4px;
  220. width: 4px;
  221. height: 212px;
  222. }
  223. .imgbg2 {
  224. position: absolute;
  225. top: 0px;
  226. left: 0px;
  227. width: 9px;
  228. height: 212px;
  229. }
  230. .courseNum {
  231. cursor: pointer;
  232. position: absolute;
  233. left: 50%;
  234. bottom: 10px;
  235. transform: translateX(-50%);
  236. background: #ffffff;
  237. padding: 0 10px;
  238. border-radius: 13px;
  239. opacity: 0.83;
  240. line-height: 25px;
  241. font-weight: 400;
  242. font-size: 16px;
  243. color: #6b3c2d;
  244. white-space: nowrap;
  245. }
  246. }
  247. .name {
  248. margin-top: 48px;
  249. font-weight: 400;
  250. font-size: 19px;
  251. color: #393939;
  252. line-height: 26px;
  253. }
  254. }
  255. }
  256. }
  257. }
  258. &:deep(.empty) {
  259. position: absolute;
  260. top: 50%;
  261. left: 50%;
  262. transform: translate(-50%, -50%);
  263. .el-empty__image {
  264. width: 360px;
  265. }
  266. }
  267. }
  268. </style>
  269. <style lang="scss">
  270. .classTypePopper.el-cascader__dropdown.el-popper {
  271. .el-cascader-menu {
  272. width: 150px;
  273. min-width: auto;
  274. }
  275. }
  276. </style>