From b8dd0584aabc5ddf4e713bcd37d5d3b2fdcf166e Mon Sep 17 00:00:00 2001 From: chenghuan Date: Thu, 11 Dec 2025 16:13:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9A1.=E8=AF=BE=E7=A8=8B?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=A2=9E=E5=8A=A0=E9=AA=A8=E6=9E=B6=E5=B1=8F?= =?UTF-8?q?=EF=BC=9B2.=E5=9B=BE=E4=B9=A6=E9=A6=96=E9=A1=B5=E5=92=8C?= =?UTF-8?q?=E5=9B=BE=E4=B9=A6=E8=AF=A6=E6=83=85=E5=A2=9E=E5=8A=A0=E9=AA=A8?= =?UTF-8?q?=E6=9E=B6=E5=B1=8F=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/clients/index.ts | 9 + api/clients/main.ts | 2 +- api/clients/skeleton.ts | 8 + api/modules/book.ts | 37 +- api/modules/book_home.ts | 21 +- api/modules/course.ts | 43 +- api/modules/video.ts | 9 +- api/types.d.ts | 1 + components/Skeleton/Skeleton.vue | 103 ++++ components/Skeleton/templates/BookCard.vue | 15 + components/Skeleton/templates/BookInfo.vue | 31 ++ components/Skeleton/templates/ImageCard.vue | 16 + components/Skeleton/templates/ImageText.vue | 17 + components/Skeleton/templates/LineList.vue | 15 + .../video-player/composables/useVideoAPI.ts | 2 +- pages/book/detail.vue | 248 +++------ pages/book/index.vue | 494 +++++++++--------- pages/book/search.vue | 6 +- pages/course/details/chapter.vue | 11 +- .../details/components/CatalogueList.vue | 287 +++++----- pages/course/details/components/Protocol.vue | 2 - pages/course/details/course.vue | 38 +- pages/user/index.vue | 8 +- style/tailwind.css | 98 ++++ types/book.d.ts | 1 - types/course.d.ts | 13 +- types/video.d.ts | 11 +- 27 files changed, 897 insertions(+), 649 deletions(-) create mode 100644 api/clients/index.ts create mode 100644 api/clients/skeleton.ts create mode 100644 components/Skeleton/Skeleton.vue create mode 100644 components/Skeleton/templates/BookCard.vue create mode 100644 components/Skeleton/templates/BookInfo.vue create mode 100644 components/Skeleton/templates/ImageCard.vue create mode 100644 components/Skeleton/templates/ImageText.vue create mode 100644 components/Skeleton/templates/LineList.vue diff --git a/api/clients/index.ts b/api/clients/index.ts new file mode 100644 index 0000000..0a08d13 --- /dev/null +++ b/api/clients/index.ts @@ -0,0 +1,9 @@ +import { skeletonClient } from './skeleton' +import { mainClient } from './main' +import { paymentClient } from './payment' + +export { + skeletonClient, + mainClient, + paymentClient +} diff --git a/api/clients/main.ts b/api/clients/main.ts index 3c849f3..705bab7 100644 --- a/api/clients/main.ts +++ b/api/clients/main.ts @@ -3,5 +3,5 @@ import { createRequestClient } from '../request'; import { SERVICE_MAP } from '../config'; export const mainClient = createRequestClient({ - baseURL: SERVICE_MAP.MAIN, + baseURL: SERVICE_MAP.MAIN }); diff --git a/api/clients/skeleton.ts b/api/clients/skeleton.ts new file mode 100644 index 0000000..a5bd0c5 --- /dev/null +++ b/api/clients/skeleton.ts @@ -0,0 +1,8 @@ +// api/clients/main.ts +import { createRequestClient } from '../request'; +import { SERVICE_MAP } from '../config'; + +export const skeletonClient = createRequestClient({ + baseURL: SERVICE_MAP.MAIN, + loading: false +}) \ No newline at end of file diff --git a/api/modules/book.ts b/api/modules/book.ts index 8d29166..67ba409 100644 --- a/api/modules/book.ts +++ b/api/modules/book.ts @@ -1,6 +1,5 @@ // api/modules/book.ts -import { createRequestClient } from '../request' -import { SERVICE_MAP } from '../config' +import { mainClient, skeletonClient } from '@/api/clients' import type { IApiResponse } from '../types' import type { IBook, @@ -13,8 +12,6 @@ import type { } from '@/types/book' import type { IGoods } from '@/types/order' -const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN }) - /** * 书籍相关API */ @@ -25,7 +22,7 @@ export const bookApi = { * @param limit 每页数量 */ getMyBooks(current: number, limit: number) { - return client.request }>>({ + return mainClient.request }>>({ url: 'bookAbroad/home/getMyBooks', method: 'POST', data: { current, limit } @@ -37,7 +34,7 @@ export const bookApi = { * @param bookId 书籍ID */ getBookInfo(bookId: number) { - return client.request>({ + return skeletonClient.request>({ url: 'bookAbroad/home/getBookInfo', method: 'POST', data: { bookId } @@ -49,7 +46,7 @@ export const bookApi = { * @param bookId 书籍ID */ getBookReadCount(bookId: number) { - return client.request>({ + return skeletonClient.request>({ url: 'bookAbroad/home/getRecommendBook', method: 'POST', data: { bookId } @@ -79,7 +76,7 @@ export const bookApi = { * @param limit 每页数量 */ getBookComments(bookId: number, current: number, limit: number) { - return client.request>({ @@ -96,7 +93,7 @@ export const bookApi = { * @param pid 父评论ID,默认为0表示顶级评论 */ insertComment(bookId: number, content: string, pid: number = 0) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/insertBookAbroadComment', method: 'POST', data: { bookId, content, pid } @@ -108,7 +105,7 @@ export const bookApi = { * @param commentId 评论ID */ likeComment(commentId: number) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/insertBookAbroadCommentLike', method: 'POST', data: { commentId } @@ -120,7 +117,7 @@ export const bookApi = { * @param commentId 评论ID */ unlikeComment(commentId: number) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/delBookAbroadCommentLike', method: 'POST', data: { commentId } @@ -132,7 +129,7 @@ export const bookApi = { * @param commentId 评论ID */ deleteComment(commentId: number) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/delBookAbroadComment', method: 'POST', data: { commentId } @@ -144,7 +141,7 @@ export const bookApi = { * @param bookId 书籍ID */ getBookChapter(data: { bookId: number; language: string }) { - return client.request>({ + return mainClient.request>({ url: 'bookAbroad/home/getBookChapter', method: 'POST', data @@ -156,7 +153,7 @@ export const bookApi = { * @param chapterId 章节ID */ getChapterContent(chapterId: number) { - return client.request>({ + return mainClient.request>({ url: 'bookAbroad/home/getBookChapterContent', method: 'POST', data: { chapterId } @@ -168,7 +165,7 @@ export const bookApi = { * @param bookId 书籍ID */ getReadProgress(bookId: number) { - return client.request>({ + return mainClient.request>({ url: 'bookAbroad/home/getBookReadRate', method: 'POST', data: { bookId } @@ -182,7 +179,7 @@ export const bookApi = { * @param contentId 内容ID */ saveReadProgress(bookId: number, chapterId: number, contentId: number) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/home/insertBookReadRate', method: 'POST', data: { bookId, chapterId, contentId } @@ -196,7 +193,7 @@ export const bookApi = { * @param contentId 内容ID */ getBookLanguages(bookId: number) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/home/getBookLanguage', method: 'POST', data: { bookId } @@ -208,7 +205,7 @@ export const bookApi = { * @param chapterId 章节ID */ getChapterContentListen(chapterId: number) { - return client.request>({ + return mainClient.request>({ url: 'bookAbroad/home/getBookChapterContentListen', method: 'POST', data: { chapterId } @@ -220,7 +217,7 @@ export const bookApi = { * @param bookId 书籍ID */ getBookGoods(bookId: number) { - return client.request>({ + return mainClient.request>({ url: 'bookAbroad/home/getProductListForBook', method: 'POST', data: { bookId } diff --git a/api/modules/book_home.ts b/api/modules/book_home.ts index 3aeaa9b..e622dc4 100644 --- a/api/modules/book_home.ts +++ b/api/modules/book_home.ts @@ -1,6 +1,5 @@ // api/modules/home.ts -import { createRequestClient } from '../request' -import { SERVICE_MAP } from '../config' +import { mainClient, skeletonClient } from '@/api/clients' import type { IMyBooksResponse, IRecommendBooksResponse, @@ -10,17 +9,15 @@ import type { ISearchResponse } from '@/types/book' -const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN }) - /** * 首页相关API */ -export const homeApi = { +export const bookHomeApi = { /** * 获取VIP信息 */ getVipInfo() { - return client.request({ + return mainClient.request({ url: 'bookAbroad/home/getVipInfo', method: 'POST', data: {} @@ -33,7 +30,7 @@ export const homeApi = { * @param limit 每页数量 */ getMyBooks(current: number, limit: number) { - return client.request({ + return skeletonClient.request({ url: 'bookAbroad/home/getMyBooks', method: 'POST', data: { current, limit } @@ -44,7 +41,7 @@ export const homeApi = { * 获取推荐图书 */ getRecommendBooks() { - return client.request({ + return skeletonClient.request({ url: 'bookAbroad/home/getRecommendBooks', method: 'POST', data: {} @@ -56,7 +53,7 @@ export const homeApi = { * @param type 0: 分类标签, 1: 活动标签 */ getBookLabelList(type: number) { - return client.request({ + return skeletonClient.request({ url: 'bookAbroad/home/getBookAbroadLableList', method: 'POST', data: { type } @@ -68,7 +65,7 @@ export const homeApi = { * @param pid 父级标签ID */ getSubLabelList(pid: number) { - return client.request({ + return skeletonClient.request({ url: 'bookAbroad/home/getBookAbroadLableListByPid', method: 'POST', data: { pid } @@ -80,7 +77,7 @@ export const homeApi = { * @param lableId 标签ID(注意:原接口参数名为 lableId) */ getBooksByLabel(lableId: number) { - return client.request({ + return skeletonClient.request({ url: 'bookAbroad/home/getAbroadBookListByLable', method: 'POST', data: { lableId } @@ -96,7 +93,7 @@ export const homeApi = { page: number, limit: number, }) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/home/searchBook', method: 'POST', data diff --git a/api/modules/course.ts b/api/modules/course.ts index e906c2d..5269bff 100644 --- a/api/modules/course.ts +++ b/api/modules/course.ts @@ -1,9 +1,8 @@ // api/modules/course.ts -import { createRequestClient } from '../request' -import { SERVICE_MAP } from '../config' +import { skeletonClient, mainClient } from '@/api/clients/index' import type { IApiResponse } from '../types' import type { - ICourseMedicalTreeResponse, + ICourseCategoryResponse, IUserLateCourseListResponse, IMarketCourseListResponse, ICourseDetailResponse, @@ -16,10 +15,6 @@ import type { ISearchRequest, ISearchResponse } from '@/types/search' import type { ICommentListResponse, IAddCommentResponse, IComment } from '@/types/comment' import { useUserStore } from '@/stores/user' - - -const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN }) - /** * 课程相关API */ @@ -29,7 +24,7 @@ export const courseApi = { * @returns 分类数据 */ getCourseMedicalTree() { - return client.request({ + return mainClient.request({ url: 'medical/home/getCourseMedicalTree', method: 'POST', data: {} @@ -41,7 +36,7 @@ export const courseApi = { * @returns 观看记录列表 */ getUserLateCourseList() { - return client.request({ + return mainClient.request({ url: 'medical/home/getUserLateCourseList', method: 'POST', data: {} @@ -61,7 +56,7 @@ export const courseApi = { limit: number }) { const userStore = useUserStore() - return client.request({ + return mainClient.request({ url: userStore.token ? 'medical/home/getMarketCourseList' : 'visitor/getMarketCourseList', method: 'POST', data @@ -74,7 +69,7 @@ export const courseApi = { * @returns 搜索结果 */ searchData(data: ISearchRequest) { - return client.request({ + return mainClient.request({ url: 'bookAbroad/home/searchCourse', method: 'POST', data @@ -86,7 +81,7 @@ export const courseApi = { * @param id 课程ID */ getCourseDetail(id: number) { - return client.request({ + return skeletonClient.request({ url: 'sociology/course/getCourseDetail', method: 'POST', data: { id } @@ -98,7 +93,7 @@ export const courseApi = { * @param id 目录ID */ getCatalogueChapterList(id: number) { - return client.request({ + return skeletonClient.request({ url: 'sociology/course/getCourseCatalogueChapterList', method: 'POST', data: { id } @@ -110,7 +105,7 @@ export const courseApi = { * @param id 章节ID */ getChapterDetail(id: number) { - return client.request({ + return skeletonClient.request({ url: 'sociology/course/getCourseCatalogueChapterDetail', method: 'POST', data: { id, load: false } @@ -122,7 +117,7 @@ export const courseApi = { * @param catalogueId 目录ID */ startStudyForMF(catalogueId: number) { - return client.request({ + return mainClient.request({ url: 'sociology/course/startStudyForMF', method: 'POST', data: { catalogueId } @@ -134,7 +129,7 @@ export const courseApi = { * @param id 目录ID */ getProductListForCourse(id: number) { - return client.request({ + return mainClient.request({ url: 'sociology/product/getProductListForCourse', method: 'POST', data: { id } @@ -146,7 +141,7 @@ export const courseApi = { * @param courseCatalogueId 目录ID */ checkRenewPayment(courseCatalogueId: number) { - return client.request>({ + return skeletonClient.request>({ url: 'common/courseRelearn/courseCatalogueCanRelearn', method: 'POST', data: { courseCatalogueId } @@ -158,7 +153,7 @@ export const courseApi = { * @param catalogueId 目录ID */ getRenewProductList(catalogueId: number) { - return client.request({ + return mainClient.request({ url: 'common/courseRelearn/relearnShopProductList', method: 'POST', data: { catalogueId } @@ -173,7 +168,7 @@ export const courseApi = { * @param userId 用户ID */ getCourseComments(courseId: number, page: number, limit: number, userId: number) { - return client.request({ + return mainClient.request({ url: 'common/courseGuestbook/getCourseGuestbookList', method: 'POST', data: { courseId, page, limit, userId, chapterId: '' } @@ -194,7 +189,7 @@ export const courseApi = { content: string images: string }) { - return client.request({ + return mainClient.request({ url: 'common/courseGuestbook/addCourseGuestbook', method: 'POST', data @@ -207,7 +202,7 @@ export const courseApi = { * @param guestbookId 留言ID */ likeComment(userId: number, guestbookId: number) { - return client.request({ + return mainClient.request({ url: 'common/courseGuestbook/addCourseGuestbookSupport', method: 'POST', data: { userId, guestbookId } @@ -220,7 +215,7 @@ export const courseApi = { * @param guestbookId 留言ID */ unlikeComment(userId: number, guestbookId: number) { - return client.request({ + return mainClient.request({ url: 'common/courseGuestbook/cancelCourseGuestbookSupport', method: 'POST', data: { userId, guestbookId } @@ -232,7 +227,7 @@ export const courseApi = { * @param courseId 课程ID */ checkCourseVip(courseId: number) { - return client.request>({ + return skeletonClient.request>({ url: 'common/userVip/ownCourseCatalogueByVip', method: 'POST', data: { courseId } @@ -244,7 +239,7 @@ export const courseApi = { * @param courseId 课程ID */ getCourseVipModule(courseId: number) { - return client.request>({ + return skeletonClient.request>({ url: 'common/userVip/getCourseVipModule', method: 'POST', data: { courseId } diff --git a/api/modules/video.ts b/api/modules/video.ts index 134d2a1..3925238 100644 --- a/api/modules/video.ts +++ b/api/modules/video.ts @@ -3,8 +3,7 @@ import { createRequestClient } from '../request' import { SERVICE_MAP } from '../config' import type { IApiResponse } from '../types' import type { IVideoCheckResponse } from '@/types/video' - -const client = createRequestClient({ baseURL: SERVICE_MAP.MAIN }) +import { skeletonClient } from '@/api/clients' /** * 视频相关API @@ -18,7 +17,7 @@ export const videoApi = { checkVideo(data: { id: number }) { - return client.request({ + return skeletonClient.request({ url: 'sociology/course/checkVideo', method: 'POST', data @@ -34,7 +33,7 @@ export const videoApi = { videoId: number position: number }) { - return client.request({ + return skeletonClient.request({ url: 'sociology/course/saveCoursePosition', method: 'POST', data @@ -51,7 +50,7 @@ export const videoApi = { videoId: number sort: number }) { - return client.request({ + return skeletonClient.request({ url: 'medical/course/addErrorCourse', method: 'POST', data diff --git a/api/types.d.ts b/api/types.d.ts index 7165b8f..67c47e1 100644 --- a/api/types.d.ts +++ b/api/types.d.ts @@ -15,6 +15,7 @@ export interface IApiResponse { */ export interface IRequestOptions extends UniApp.RequestOptions { // 允许扩展额外字段(例如 FILE 上传专用等) + headers?: Record; maxSize?: number; files?: Array<{ name: string; uri: string; fileType?: string }>; } diff --git a/components/Skeleton/Skeleton.vue b/components/Skeleton/Skeleton.vue new file mode 100644 index 0000000..f841ca2 --- /dev/null +++ b/components/Skeleton/Skeleton.vue @@ -0,0 +1,103 @@ + + + + + \ No newline at end of file diff --git a/components/Skeleton/templates/BookCard.vue b/components/Skeleton/templates/BookCard.vue new file mode 100644 index 0000000..0f83df6 --- /dev/null +++ b/components/Skeleton/templates/BookCard.vue @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/components/Skeleton/templates/BookInfo.vue b/components/Skeleton/templates/BookInfo.vue new file mode 100644 index 0000000..8559c58 --- /dev/null +++ b/components/Skeleton/templates/BookInfo.vue @@ -0,0 +1,31 @@ + + + + + \ No newline at end of file diff --git a/components/Skeleton/templates/ImageCard.vue b/components/Skeleton/templates/ImageCard.vue new file mode 100644 index 0000000..317cb13 --- /dev/null +++ b/components/Skeleton/templates/ImageCard.vue @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/components/Skeleton/templates/ImageText.vue b/components/Skeleton/templates/ImageText.vue new file mode 100644 index 0000000..01f7a87 --- /dev/null +++ b/components/Skeleton/templates/ImageText.vue @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/components/Skeleton/templates/LineList.vue b/components/Skeleton/templates/LineList.vue new file mode 100644 index 0000000..0f83df6 --- /dev/null +++ b/components/Skeleton/templates/LineList.vue @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/components/video-player/composables/useVideoAPI.ts b/components/video-player/composables/useVideoAPI.ts index 28feff7..dce309e 100644 --- a/components/video-player/composables/useVideoAPI.ts +++ b/components/video-player/composables/useVideoAPI.ts @@ -31,7 +31,7 @@ export function useVideoAPI() { } catch (err: any) { console.error('Failed to fetch video info:', err) error.value = { - type: 'API_ERROR', + type: 'API_ERROR' as VideoErrorType, message: err.message || '获取视频信息失败,请稍后重试' } return null diff --git a/pages/book/detail.vue b/pages/book/detail.vue index 9ef2c8d..a2f75e5 100644 --- a/pages/book/detail.vue +++ b/pages/book/detail.vue @@ -3,82 +3,76 @@ - - - - - {{ bookInfo.name }} - {{ $t('bookDetails.authorName') }}{{ bookInfo.author?.authorName }} - - - - - - {{ readCount }}{{ $t('bookHome.readingCount') }} - - - - - {{ listenCount }}{{ $t('bookHome.listenCount') }} - - - - - {{ buyCount }}{{ $t('bookHome.purchased') }} - - - - - - - {{ $t('bookDetails.introduction') }} - {{ bookInfo.author?.introduction }} - - - - - - - - {{ $t('bookDetails.relatedBooks') }} - - - - - {{ item.name }} + + + + + + {{ $t('bookDetails.relatedBooks') }} + + + + + - +