MoreCourse.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <div class="course-content">
  3. <div class="course-header">
  4. <span class="course-header-title">{{ props.title }}</span>
  5. </div>
  6. <div class="course-content-container">
  7. <div class="course-content-title">
  8. <el-button :icon="Refresh" circle @click="doRefresh" style="margin: 0 10px 0 30px"></el-button>
  9. <el-input v-model="courseName" placeholder="请输入课程名称" clearable class="search-input" style="width: 180px; margin-right: 10px"/>
  10. <el-button @click="handleSearch" color="#597D3B">
  11. <el-icon style="margin-right: 3px" ><Search/></el-icon>
  12. 查询
  13. </el-button>
  14. </div>
  15. <div class="course-items-container">
  16. <el-card v-for="item in getCoursesSlice(0, 5)" :key="item.courseId" class="course-item active" @click="handleClick(item.courseId)">
  17. <div style="width: 200px; height: 120px">
  18. <img :src="convertImageUrl(item.courseImages?.[0] ?? null, item.courseName)" :alt="item.courseName" class="course-item-img">
  19. </div>
  20. <div class="course-item-content">
  21. <div style="font-weight: bold; font-size: 16px; margin: 5px 0">{{item.courseName}}</div>
  22. <div style="line-height: 1.5" class="collapsed" ><span style="color: rgba(0, 0, 0, 0.6)">课程描述:</span>{{item.description}}</div>
  23. <div style="line-height: 1.5; margin-top: 5px" class="collapsed" ><span style="color: rgba(0, 0, 0, 0.6)">任课教师:</span>{{item.teacherNames.join(",")}}</div>
  24. </div>
  25. </el-card>
  26. <template v-if="getCoursesSlice(0, 5).length < 5">
  27. <el-card v-for="item in 5 - getCoursesSlice(0, 5).length" :key="item" class="course-item-hidden">
  28. </el-card>
  29. </template>
  30. </div>
  31. <div class="course-items-container">
  32. <el-card v-for="item in getCoursesSlice(5, 10)" :key="item.courseId" class="course-item active" @click="handleClick(item.courseId)">
  33. <div style="width: 200px; height: 120px">
  34. <img :src="convertImageUrl(item.courseImages[0], item.courseName)" :alt="item.courseName" class="course-item-img">
  35. </div>
  36. <div class="course-item-content">
  37. <div style="font-weight: bold; font-size: 16px; margin: 5px 0">{{item.courseName}}</div>
  38. <div style="line-height: 1.5" class="collapsed" ><span style="color: rgba(0, 0, 0, 0.6)">课程描述:</span>{{item.description}}</div>
  39. <div style="line-height: 1.5; margin-top: 5px" class="collapsed" ><span style="color: rgba(0, 0, 0, 0.6)">任课教师:</span>{{item.teacherNames.join(",")}}</div>
  40. </div>
  41. </el-card>
  42. <template v-if="getCoursesSlice(5, 10).length < 5">
  43. <el-card v-for="item in 5 - getCoursesSlice(5, 10).length" :key="item" class="course-item-hidden">
  44. </el-card>
  45. </template>
  46. </div>
  47. <el-pagination
  48. small
  49. style="font-size: 16px;margin-top: 10px;margin-left: 450px"
  50. @current-change="handleCurrentChange"
  51. :current-page="queryInfo.pageNow"
  52. :page-size="queryInfo.pageSize"
  53. layout="total, prev, pager, next, jumper"
  54. :total="pageInfo.total">
  55. </el-pagination>
  56. </div>
  57. </div>
  58. </template>
  59. <script lang="ts" setup>
  60. import './MoreCourse.scss'
  61. import {defineProps, inject, onMounted, reactive, ref} from "vue";
  62. import useApis from "@/apis";
  63. import type {CourseQuery} from "@/types/query";
  64. import router from "@/router";
  65. import {useStore} from "@/store";
  66. import {Refresh, Search} from "@element-plus/icons-vue";
  67. import {convertImageUrl} from "@/utils/convertUtil";
  68. const apis = useApis()
  69. const store = useStore()
  70. const doRefresh:Function = inject("reload")
  71. const role:'teachers' | 'student' = store.user.role === 'STUDENT' ? 'student':'teachers';
  72. let courseName = ref('')
  73. const props = defineProps<{
  74. title: string;
  75. type: 'all' | 'my'
  76. }>()
  77. const queryInfo = reactive({
  78. pageNow: 1,
  79. pageSize: 10,
  80. })
  81. let pageInfo = reactive({
  82. total: 0,
  83. courseData: []
  84. })
  85. let pageInfo2Show = reactive({
  86. total: 0,
  87. courseData: []
  88. })
  89. const query = reactive<CourseQuery>({
  90. courseId:null,
  91. teacherId:null,
  92. studentId:null,
  93. courseName:null,
  94. semester:null,
  95. })
  96. const handleSearch = () => {
  97. if(props.type == 'all'){
  98. Object.assign(query, {
  99. courseId:null,
  100. teacherId:null,
  101. studentId:null,
  102. courseName:courseName.value,
  103. semester:null,
  104. })
  105. fetchAllCourse()
  106. } else {
  107. if(role == 'student'){
  108. Object.assign(query, {
  109. courseId:null,
  110. teacherId:null,
  111. studentId:store.user.id,
  112. courseName:courseName.value,
  113. semester:null,
  114. })
  115. fetchAllCourse()
  116. }else {
  117. Object.assign(query, {
  118. courseId:null,
  119. teacherId:store.user.id,
  120. studentId:null,
  121. courseName:courseName.value,
  122. semester:null,
  123. })
  124. fetchAllCourse()
  125. }
  126. }
  127. }
  128. const courseNameFilter = () => {
  129. Object.assign(pageInfo2Show, {
  130. total: 0,
  131. courseData: []
  132. })
  133. for(let i = 0; i < pageInfo.total; i++){
  134. if(pageInfo.courseData[i].courseName.includes(courseName.value)){
  135. pageInfo2Show.courseData.push(pageInfo.courseData[i])
  136. pageInfo2Show.total++;
  137. }
  138. }
  139. }
  140. // 处理课程卡片的点击事件
  141. const handleClick = (value:number) => {
  142. router.push(`/home/courseDetail/${value}`)
  143. }
  144. const handleCurrentChange =(index:number)=>{
  145. queryInfo.pageNow=index;
  146. fetchData();
  147. }
  148. const fetchData = () => {
  149. if(props.type === 'all'){
  150. fetchAllCourse()
  151. } else if(props.type === 'my'){
  152. fetchCourseByUserId()
  153. }else{
  154. alert("获取课程失败")
  155. }
  156. }
  157. const fetchAllCourse = () => {
  158. apis.getAllCourse(query, queryInfo.pageNow, queryInfo.pageSize)
  159. .then((res: any) => {
  160. console.log(res)
  161. pageInfo.courseData = res.data.data.records
  162. pageInfo.total = res.data.data.total
  163. Object.assign(pageInfo2Show, pageInfo)
  164. })
  165. .catch((err: any) => {
  166. console.error("错误信息",err);
  167. })
  168. .finally(() => {});
  169. }
  170. const fetchCourseByUserId = () => {
  171. if(role === 'student'){
  172. apis.getCourseByStudentId(queryInfo.pageNow, queryInfo.pageSize)
  173. .then((res: any) => {
  174. console.log(res)
  175. pageInfo.courseData = res.data.data.records
  176. pageInfo.total = res.data.data.total
  177. Object.assign(pageInfo2Show, pageInfo)
  178. })
  179. .catch((err: any) => {
  180. console.error(err);
  181. })
  182. .finally(() => {});
  183. } else if(role === "teachers"){
  184. apis.getCourseByTeacherId(queryInfo.pageNow, queryInfo.pageSize)
  185. .then((res: any) => {
  186. console.log(res.data.data)
  187. pageInfo.courseData = res.data.data.records
  188. pageInfo.total = res.data.data.total
  189. Object.assign(pageInfo2Show, pageInfo)
  190. })
  191. .catch((err: any) => {
  192. console.error(err);
  193. })
  194. .finally(() => {});
  195. }
  196. }
  197. //只获取前五个课程
  198. const getCoursesSlice = (start:number, end:number) => {
  199. return pageInfo2Show.courseData.slice(start, end)
  200. }
  201. onMounted(()=>{
  202. fetchData()
  203. })
  204. </script>
  205. <script lang="ts">
  206. export default {
  207. name: "AllCourse"
  208. }
  209. </script>
  210. <style scoped>
  211. .collapsed {
  212. overflow: hidden;
  213. display: -webkit-box;
  214. -webkit-box-orient: vertical;
  215. -webkit-line-clamp: 2; /* Limit to 2 lines */
  216. max-height: 3em; /* Height for 2 lines of text */
  217. min-height: 3em;
  218. }
  219. </style>