diff --git a/api/interceptors/response.ts b/api/interceptors/response.ts index aa90e85..7e0236e 100644 --- a/api/interceptors/response.ts +++ b/api/interceptors/response.ts @@ -34,7 +34,7 @@ export function responseInterceptor(res: UniApp.RequestSuccessCallbackResult) { } // 可能为字符串,尝试解析(原项目也做了类似处理) - let httpData: IApiResponse | string = res.data as any; + let httpData: IApiResponse | string = res.data; if (typeof httpData === 'string') { try { httpData = JSON.parse(httpData); @@ -44,19 +44,20 @@ export function responseInterceptor(res: UniApp.RequestSuccessCallbackResult) { } // 规范化 message 字段 - const message = (httpData as any).msg || (httpData as any).message || (httpData as any).errMsg || ''; + const message = (httpData as IApiResponse).msg || (httpData as IApiResponse).message || (httpData as IApiResponse).errMsg || ''; - // 成功判断:与原项目一致的条件 - const successFlag = (httpData as any).success === true || (httpData as any).code === 0; + const code = (httpData as IApiResponse).code; + + // 成功判断 + const successFlag = (httpData as IApiResponse).success === true || code === 0; if (successFlag) { - // 返回原始 httpData(与原项目 dataFactory 返回 Promise.resolve(httpData) 保持一致) - // 但大多数调用者更关心 data 字段,这里返回整个 httpData,调用者可取 .data + // 返回原始 httpData + // 实际数据每个接口不同,调用者需根据实际情况取 .data 字段 return Promise.resolve(httpData); } - // 登录失效或需要强制登录的一些 code(与原项目一致) - const code = (httpData as any).code; + // 登录失效或需要强制登录的一些 code if (code === '401' || code === 401) { // 触发登出流程 handleAuthExpired(); @@ -64,7 +65,7 @@ export function responseInterceptor(res: UniApp.RequestSuccessCallbackResult) { } // 原项目还将 1000,1001,1100,402 等视作需要强制登录 - if (code === '1000' || code === '1001' || code === 1000 || code === 1001 || code === 1100 || code === '402' || code === 402) { + if (code == 1000 || code == 1001 || code === 1100 || code === 402) { handleAuthExpired(); return Promise.reject({ statusCode: 0, errMsg: message || t('global.loginExpired'), data: httpData }); } diff --git a/api/modules/user.ts b/api/modules/user.ts index 8aef89d..a411c7c 100644 --- a/api/modules/user.ts +++ b/api/modules/user.ts @@ -253,4 +253,16 @@ export async function getActivityDescription() { method: 'POST' }) return res +} + +/** + * 获取充值列表 + */ +export async function getTransactionDetailsList(current: number, limit: number, userId: string,) { + const res = await mainClient.request({ + url: 'common/transactionDetails/getTransactionDetailsList', + method: 'POST', + data: { current, limit, userId, } + }) + return res } \ No newline at end of file diff --git a/api/request.ts b/api/request.ts index b908f14..3f5f7a9 100644 --- a/api/request.ts +++ b/api/request.ts @@ -8,6 +8,7 @@ import { t } from '@/utils/i18n' export function createRequestClient(cfg: ICreateClientConfig) { const baseURL = cfg.baseURL; const timeout = cfg.timeout ?? REQUEST_TIMEOUT; + let reqCount= 0 async function request(options: IRequestOptions): Promise { // 组装 final options @@ -23,14 +24,18 @@ export function createRequestClient(cfg: ICreateClientConfig) { // 全局处理请求 loading const loading = !cfg.loading ? true : cfg.loading // 接口请求参数不传loading,默认显示loading - loading && uni.showLoading() + if (loading) { + uni.showLoading({ mask: true }) + reqCount++ + } return new Promise((resolve, reject) => { uni.request({ ...intercepted, complete() { // 请求完成关闭 loading - loading && uni.hideLoading() + loading && reqCount-- + reqCount <= 0 && uni.hideLoading() }, success(res: any) { // 委托给响应拦截器处理 diff --git a/components/order/Confirm.vue b/components/order/Confirm.vue index cfb1f0a..46af04e 100644 --- a/components/order/Confirm.vue +++ b/components/order/Confirm.vue @@ -90,7 +90,7 @@ {{ $t('order.total') }}: {{ finalAmount }} {{ t('global.coin') }} - + {{ $t('order.submit') }} @@ -170,12 +170,7 @@ const getDiscountParams = (goodsList: IGoods[]) => { })) } - -// 支付相关 - -// UI状态 -const submitting = ref(false) - +// 监听商品列表变化,更新价格 watch(() => props.goodsList, () => { getDiscountParams(props.goodsList) // 初始化价格 @@ -222,24 +217,16 @@ const calculateTotalPrice = () => { * 计算VIP优惠 */ const calculateVipDiscounted = async () => { - try { - const res = await orderApi.getVipDiscountAmount(goodsListParams.value) - vipDiscounted.value = res.discountAmount - } catch (error) { - console.error('获取VIP优惠失败:', error) - } + const res = await orderApi.getVipDiscountAmount(goodsListParams.value) + vipDiscounted.value = res.discountAmount } /** * 计算活动优惠 */ const calculatePromotionDiscounted = async () => { - try { - const res = await orderApi.getDistrictAmount(goodsListParams.value) - promotionDiscounted.value = res.districtAmount - } catch (error) { - console.error('获取地区优惠失败:', error) - } + const res = await orderApi.getDistrictAmount(goodsListParams.value) + promotionDiscounted.value = res.districtAmount } /** @@ -363,71 +350,45 @@ const validateOrder = (): boolean => { /** * 提交订单 */ -const handleSubmit = async () => { - if (submitting.value) { - uni.showToast({ - title: t('order.tooFrequent'), - icon: 'none' - }) - return - } - +const handleSubmit = async () => { // 验证订单 if (!validateOrder()) return - - try { - submitting.value = true - - // 创建订单 此app用天医币支付,创建订单成功即支付成功 - await createOrder() - uni.showToast({ - title: t('order.orderSuccess'), - icon: 'success' - }) - - } catch (error) { - console.error('提交订单失败:', error) - uni.showToast({ - title: t('order.orderFailed'), - icon: 'none' - }) - } finally { - submitting.value = false - } + // 创建订单 此app用天医币支付,创建订单成功即支付成功 + await createOrder() + + uni.showToast({ + title: t('order.orderSuccess'), + icon: 'success' + }) } /** * 创建订单 */ const createOrder = async (): Promise => { - try { - const orderParams = { - userId: props.userInfo.id, - paymentMethod: 4, // 天医币 - orderMoney: totalAmount.value, - realMoney: finalAmount.value, - pointsDeduction: pointsDiscounted.value, - // couponId: selectedCoupon.value?.id, - // couponName: selectedCoupon.value?.couponEntity.couponName, - vipDiscountAmount: vipDiscounted.value, - districtMoney: promotionDiscounted.value, - remark: remark.value, - productList: goodsListParams.value, - orderType: props.orderType, - come: 10 - } - - const res = await orderApi.placeCourseOrder(orderParams) - - if (res.orderSn) { - return res.orderSn - } - return null - } catch (error) { - console.error('下单失败:', error) - throw error + const orderParams = { + userId: props.userInfo.id, + paymentMethod: 4, // 天医币 + orderMoney: totalAmount.value, + realMoney: finalAmount.value, + pointsDeduction: pointsDiscounted.value, + // couponId: selectedCoupon.value?.id, + // couponName: selectedCoupon.value?.couponEntity.couponName, + vipDiscountAmount: vipDiscounted.value, + districtMoney: promotionDiscounted.value, + remark: remark.value, + productList: goodsListParams.value, + orderType: props.orderType, + come: 10 } + + const res = await orderApi.placeCourseOrder(orderParams) + + if (res.orderSn) { + return res.orderSn + } + return null } diff --git a/locale/en.json b/locale/en.json index 4d55335..5f7464d 100644 --- a/locale/en.json +++ b/locale/en.json @@ -208,7 +208,8 @@ "seasonCard": "Quarterly", "yearCard": "Yearly", "days": "days", - "selectPackage": "Please select a package" + "selectPackage": "Please select a package", + "consumptionRecord": "Consumption record" }, "book": { "title": "My Books", @@ -467,6 +468,11 @@ "couponType0": "All Products", "couponType1": "Specific Courses", "couponType2": "Course Categories", - "couponCount": "{count} coupons" + "couponCount": "{count} coupons", + "rechargeConsumptionList": "Recharge and consumption records", + "rechargeAmount": "Recharge amount", + "valueAddedServices": "Value-added services", + "readAgree": "I have read and agreed", + "readAgreeServices": "Please read and agree to the value-added services first" } } diff --git a/locale/zh-Hans.json b/locale/zh-Hans.json index 22f95e3..4faf8b7 100644 --- a/locale/zh-Hans.json +++ b/locale/zh-Hans.json @@ -209,7 +209,8 @@ "seasonCard": "季卡", "yearCard": "年卡", "days": "天", - "selectPackage": "请选择套餐" + "selectPackage": "请选择套餐", + "consumptionRecord": "消费记录" }, "book": { "title": "我的书单", @@ -468,6 +469,11 @@ "couponType0": "全场通用", "couponType1": "指定课程可用", "couponType2": "指定课程品类可用", - "couponCount": "共 {count} 张" + "couponCount": "共 {count} 张", + "rechargeConsumptionList": "充值消费记录", + "rechargeAmount": "充值金额", + "valueAddedServices": "增值服务", + "readAgree": "我已阅读并同意", + "readAgreeServices": "请先阅读并同意增值服务" } } diff --git a/pages/book/detail.vue b/pages/book/detail.vue index 01b5002..831a519 100644 --- a/pages/book/detail.vue +++ b/pages/book/detail.vue @@ -230,70 +230,43 @@ function initScrollHeight() { // 加载书籍详情 async function loadBookInfo() { - try { - const res = await bookApi.getBookInfo(bookId.value) - - if (res.bookInfo) { - bookInfo.value = res.bookInfo - } - } catch (error) { - console.error('Failed to load book info:', error) - } + const res = await bookApi.getBookInfo(bookId.value) + bookInfo.value = res.bookInfo } // 加载购买商品信息 async function loadGoodsInfo() { - try { - const res = await bookApi.getBookGoods(bookId.value) - if (res.code === 0) { - goodsList.value = res.productList || [] - } - } catch (error) { - console.error('Failed to load goods info:', error) - } + const res = await bookApi.getBookGoods(bookId.value) + goodsList.value = res.productList || [] } // 加载统计数据 async function loadBookCount() { - try { - const res = await bookApi.getBookReadCount(bookId.value) - if (res.code === 0) { - readCount.value = res.readCount || 0 - listenCount.value = res.listenCount || 0 - buyCount.value = res.buyCount || 0 - } - } catch (error) { - console.error('Failed to load book count:', error) + const res = await bookApi.getBookReadCount(bookId.value) + if (res.code === 0) { + readCount.value = res.readCount || 0 + listenCount.value = res.listenCount || 0 + buyCount.value = res.buyCount || 0 } } // 加载评论 async function loadComments() { - try { - const res = await bookApi.getBookComments(bookId.value, 1, 10) - if (res.commentsTree && res.commentsTree.length > 0) { - commentList.value = res.commentsTree - } else { - nullText.value = t('common.data_null') - } - } catch (error) { + const res = await bookApi.getBookComments(bookId.value, 1, 10) + if (res.commentsTree && res.commentsTree.length > 0) { + commentList.value = res.commentsTree + } else { nullText.value = t('common.data_null') - console.error('Failed to load comments:', error) } } // 加载推荐书籍 async function loadRecommendBooks() { - try { - const res = await bookApi.getRecommendBook(bookId.value) - if (res.bookList && res.bookList.length > 0) { - relatedBooks.value = res.bookList - } else { - nullBookText.value = t('common.data_null') - } - } catch (error) { + const res = await bookApi.getRecommendBook(bookId.value) + if (res.bookList && res.bookList.length > 0) { + relatedBooks.value = res.bookList + } else { nullBookText.value = t('common.data_null') - console.error('Failed to load recommend books:', error) } } diff --git a/pages/book/index.vue b/pages/book/index.vue index ca7e4a7..1a570a7 100644 --- a/pages/book/index.vue +++ b/pages/book/index.vue @@ -219,13 +219,9 @@ const vipInfo = ref(null) * 获取VIP信息 */ const getVipInfo = async () => { - try { - const res = await homeApi.getVipInfo() - if (res.vipInfo) { - vipInfo.value = res.vipInfo - } - } catch (error) { - console.error('获取VIP信息失败:', error) + const res = await homeApi.getVipInfo() + if (res.vipInfo) { + vipInfo.value = res.vipInfo } } @@ -233,21 +229,17 @@ const getVipInfo = async () => { * 获取我的书单 */ const getMyBooks = async () => { - try { - const res = await homeApi.getMyBooks(1, 10) - if (res && res.code === 0) { - showMyBooks.value = true - if (res.page.records && res.page.records.length > 0) { - myBooksList.value = res.page.records - } - } else { - // 未登录,跳转到登录页 - uni.navigateTo({ - url: '/pages/login/login' - }) + const res = await homeApi.getMyBooks(1, 10) + if (res && res.code === 0) { + showMyBooks.value = true + if (res.page.records && res.page.records.length > 0) { + myBooksList.value = res.page.records } - } catch (error) { - console.error('获取我的书单失败:', error) + } else { + // 未登录,跳转到登录页 + uni.navigateTo({ + url: '/pages/login/login' + }) } } @@ -255,13 +247,9 @@ const getMyBooks = async () => { * 获取推荐图书 */ const getRecommendBooks = async () => { - try { - const res = await homeApi.getRecommendBooks() - if (res.books && res.books.length > 0) { - recommendBooksList.value = res.books - } - } catch (error) { - console.error('获取推荐图书失败:', error) + const res = await homeApi.getRecommendBooks() + if (res.books && res.books.length > 0) { + recommendBooksList.value = res.books } } @@ -269,16 +257,12 @@ const getRecommendBooks = async () => { * 获取活动标签列表 */ const getActivityLabels = async () => { - try { - const res = await homeApi.getBookLabelList(1) - showActivity.value = true - if (res.lableList && res.lableList.length > 0) { - activityLabelList.value = res.lableList - // 默认加载第一个标签的图书列表 - await getBooksByLabel(res.lableList[0].id, 'activity') - } - } catch (error) { - console.error('获取活动标签失败:', error) + const res = await homeApi.getBookLabelList(1) + showActivity.value = true + if (res.lableList && res.lableList.length > 0) { + activityLabelList.value = res.lableList + // 默认加载第一个标签的图书列表 + await getBooksByLabel(res.lableList[0].id, 'activity') } } @@ -286,16 +270,12 @@ const getActivityLabels = async () => { * 获取分类标签列表 */ const getCategoryLabels = async () => { - try { - const res = await homeApi.getBookLabelList(0) - showCategory.value = true - if (res.lableList && res.lableList.length > 0) { - categoryLevel1List.value = res.lableList - // 默认加载第一个标签的二级标签 - await getSubLabels(res.lableList[0].id, 0) - } - } catch (error) { - console.error('获取分类标签失败:', error) + const res = await homeApi.getBookLabelList(0) + showCategory.value = true + if (res.lableList && res.lableList.length > 0) { + categoryLevel1List.value = res.lableList + // 默认加载第一个标签的二级标签 + await getSubLabels(res.lableList[0].id, 0) } } @@ -303,21 +283,17 @@ const getCategoryLabels = async () => { * 获取二级标签列表 */ const getSubLabels = async (pid: number, index: number) => { - try { - const res = await homeApi.getSubLabelList(pid) - currentLevel1Index.value = index - if (res.lableList && res.lableList.length > 0) { - categoryLevel2List.value = res.lableList - currentLevel2Index.value = 0 - // 加载第一个二级标签的图书列表 - await getBooksByLabel(res.lableList[0].id, 'category') - } else { - // 没有二级标签,直接加载一级标签的图书列表 - categoryLevel2List.value = [] - await getBooksByLabel(pid, 'category') - } - } catch (error) { - console.error('获取二级标签失败:', error) + const res = await homeApi.getSubLabelList(pid) + currentLevel1Index.value = index + if (res.lableList && res.lableList.length > 0) { + categoryLevel2List.value = res.lableList + currentLevel2Index.value = 0 + // 加载第一个二级标签的图书列表 + await getBooksByLabel(res.lableList[0].id, 'category') + } else { + // 没有二级标签,直接加载一级标签的图书列表 + categoryLevel2List.value = [] + await getBooksByLabel(pid, 'category') } } @@ -328,23 +304,19 @@ const getBooksByLabel = async ( labelId: number, type: 'activity' | 'category' ) => { - try { - const res = await homeApi.getBooksByLabel(labelId) - if (type === 'activity') { - if (res.bookList && res.bookList.length > 0) { - activityList.value = res.bookList - } else { - activityList.value = [] - } + const res = await homeApi.getBooksByLabel(labelId) + if (type === 'activity') { + if (res.bookList && res.bookList.length > 0) { + activityList.value = res.bookList } else { - if (res.bookList && res.bookList.length > 0) { - categoryBookList.value = res.bookList - } else { - categoryBookList.value = [] - } + activityList.value = [] + } + } else { + if (res.bookList && res.bookList.length > 0) { + categoryBookList.value = res.bookList + } else { + categoryBookList.value = [] } - } catch (error) { - console.error('获取图书列表失败:', error) } } diff --git a/pages/book/listen/index.vue b/pages/book/listen/index.vue index 5c52f2f..85261d5 100644 --- a/pages/book/listen/index.vue +++ b/pages/book/listen/index.vue @@ -117,31 +117,20 @@ function initScrollHeight() { // 加载书籍信息 async function loadBookInfo() { - try { - const res = await bookApi.getBookInfo(bookId.value) - if (res.bookInfo) { - bookInfo.value = res.bookInfo - } - } catch (error) { - console.error('Failed to load book info:', error) - } + const res = await bookApi.getBookInfo(bookId.value) + bookInfo.value = res.bookInfo } // 加载章节列表 async function loadChapterList() { - try { - const res = await bookApi.getBookChapter({ - bookId: bookId.value - }) - - if (res.chapterList && res.chapterList.length > 0) { - chapterList.value = res.chapterList - } else { - nullText.value = t('common.data_null') - } - } catch (error) { + const res = await bookApi.getBookChapter({ + bookId: bookId.value + }) + + if (res.chapterList && res.chapterList.length > 0) { + chapterList.value = res.chapterList + } else { nullText.value = t('common.data_null') - console.error('Failed to load chapter list:', error) } } diff --git a/pages/book/listen/player.vue b/pages/book/listen/player.vue index 39ac74a..809e5bd 100644 --- a/pages/book/listen/player.vue +++ b/pages/book/listen/player.vue @@ -245,14 +245,8 @@ function initAudioContext() { // 加载书籍信息 async function loadBookInfo() { - try { - const res = await bookApi.getBookInfo(bookId.value) - if (res.bookInfo) { - bookInfo.value = res.bookInfo - } - } catch (error) { - console.error('Failed to load book info:', error) - } + const res = await bookApi.getBookInfo(bookId.value) + bookInfo.value = res.bookInfo } // 加载章节列表 diff --git a/pages/book/review.vue b/pages/book/review.vue index 246772f..53d42f7 100644 --- a/pages/book/review.vue +++ b/pages/book/review.vue @@ -164,13 +164,9 @@ function initScrollHeight() { // 加载书籍信息 async function loadBookInfo() { - try { - const res = await bookApi.getBookInfo(bookId.value) - if (res.bookInfo) { - bookInfo.value = res.bookInfo - } - } catch (error) { - console.error('Failed to load book info:', error) + const res = await bookApi.getBookInfo(bookId.value) + if (res.bookInfo) { + bookInfo.value = res.bookInfo } } @@ -180,20 +176,15 @@ async function loadComments() { return } - try { - const res = await bookApi.getBookComments(bookId.value, page.value.current, page.value.limit) + const res = await bookApi.getBookComments(bookId.value, page.value.current, page.value.limit) - commentsCount.value = res.commentsCount || 0 - - if (res.commentsTree && res.commentsTree.length > 0) { - commentList.value = [...commentList.value, ...res.commentsTree] - page.value.current += 1 - } else if (commentList.value.length === 0) { - nullText.value = t('common.data_null') - } - } catch (error) { + commentsCount.value = res.commentsCount || 0 + + if (res.commentsTree && res.commentsTree.length > 0) { + commentList.value = [...commentList.value, ...res.commentsTree] + page.value.current += 1 + } else if (commentList.value.length === 0) { nullText.value = t('common.data_null') - console.error('Failed to load comments:', error) } } @@ -275,33 +266,29 @@ function handleEmj(i: any) { // 提交评论 async function submitComment() { - try { - const content = await getEditorContent() - - if (!content || content === '


') { - uni.showToast({ - title: t('bookDetails.enterText'), - icon: 'none' - }) - return - } - - const pid = replyTarget.value?.id || 0 - await bookApi.insertComment(bookId.value, content, pid) + const content = await getEditorContent() + if (!content || content === '


') { uni.showToast({ - title: t('workOrder.submit_success'), - icon: 'success', - duration: 500 + title: t('bookDetails.enterText'), + icon: 'none' }) - - setTimeout(() => { - editorCtx.value?.clear() - resetComments() - }, 500) - } catch (error) { - console.error('Failed to submit comment:', error) + return } + + const pid = replyTarget.value?.id || 0 + await bookApi.insertComment(bookId.value, content, pid) + + uni.showToast({ + title: t('workOrder.submit_success'), + icon: 'success', + duration: 500 + }) + + setTimeout(() => { + editorCtx.value?.clear() + resetComments() + }, 500) } // 点赞/取消点赞 @@ -314,29 +301,25 @@ async function handleLike(comment: IComment) { return } - try { - if (comment.isLike === 0) { - await bookApi.likeComment(comment.id) - uni.showToast({ - title: t('bookDetails.supportSuccess'), - icon: 'success', - duration: 1000 - }) - } else { - await bookApi.unlikeComment(comment.id) - uni.showToast({ - title: t('bookDetails.supportCancel'), - icon: 'success', - duration: 1000 - }) - } - - setTimeout(() => { - resetComments() - }, 200) - } catch (error) { - console.error('Failed to like comment:', error) + if (comment.isLike === 0) { + await bookApi.likeComment(comment.id) + uni.showToast({ + title: t('bookDetails.supportSuccess'), + icon: 'success', + duration: 1000 + }) + } else { + await bookApi.unlikeComment(comment.id) + uni.showToast({ + title: t('bookDetails.supportCancel'), + icon: 'success', + duration: 1000 + }) } + + setTimeout(() => { + resetComments() + }, 200) } // 删除评论 @@ -348,20 +331,16 @@ function handleDelete(comment: IComment) { confirmText: t('common.confirm_text'), success: async (res) => { if (res.confirm) { - try { - await bookApi.deleteComment(comment.id) - uni.showToast({ - title: t('bookDetails.deleteSuccess'), - icon: 'success', - duration: 500 - }) - - setTimeout(() => { - resetComments() - }, 500) - } catch (error) { - console.error('Failed to delete comment:', error) - } + await bookApi.deleteComment(comment.id) + uni.showToast({ + title: t('bookDetails.deleteSuccess'), + icon: 'success', + duration: 500 + }) + + setTimeout(() => { + resetComments() + }, 500) } } }) diff --git a/pages/book/search.vue b/pages/book/search.vue index a4d2a8e..1bf1b0e 100644 --- a/pages/book/search.vue +++ b/pages/book/search.vue @@ -70,14 +70,8 @@ onLoad((options: any) => { * 获取VIP信息 */ const getVipInfo = async () => { - try { - const res = await homeApi.getVipInfo() - if (res.vipInfo) { - vipInfo.value = res.vipInfo - } - } catch (error) { - console.error('获取VIP信息失败:', error) - } + const res = await homeApi.getVipInfo() + vipInfo.value = res.vipInfo } /** @@ -91,26 +85,19 @@ const handleSearch = async () => { loading.value = true isEmpty.value = false - try { - const res = await homeApi.searchBooks({ - title: keyword.value.trim(), - page: 1, - limit: 10, - }) - if (res.bookList && res.bookList.length > 0) { - searchResults.value = res.bookList - isEmpty.value = false - } else { - searchResults.value = [] - isEmpty.value = true - } - } catch (error) { - console.error('搜索失败:', error) + const res = await homeApi.searchBooks({ + title: keyword.value.trim(), + page: 1, + limit: 10, + }) + if (res.bookList && res.bookList.length > 0) { + searchResults.value = res.bookList + isEmpty.value = false + } else { searchResults.value = [] isEmpty.value = true - } finally { - loading.value = false } + loading.value = false } /** diff --git a/pages/course/details/chapter.vue b/pages/course/details/chapter.vue index 3e5206c..186c37d 100644 --- a/pages/course/details/chapter.vue +++ b/pages/course/details/chapter.vue @@ -164,23 +164,19 @@ onLoad((options: any) => { * 加载章节详情 */ const loadChapterDetail = async () => { - try { - const res = await courseApi.getChapterDetail(chapterId.value) - if (res.code === 0 && res.data) { - chapterDetail.value = res.data.detail - videoList.value = res.data.videos || [] + const res = await courseApi.getChapterDetail(chapterId.value) + if (res.code === 0 && res.data) { + chapterDetail.value = res.data.detail + videoList.value = res.data.videos || [] - // 如果有历史播放记录,定位到对应视频 - if (res.data.current) { - const index = videoList.value.findIndex(v => v.id === res.data.current) - if (index !== -1) { - currentVideoIndex.value = index - activeVideoIndex.value = index - } + // 如果有历史播放记录,定位到对应视频 + if (res.data.current) { + const index = videoList.value.findIndex(v => v.id === res.data.current) + if (index !== -1) { + currentVideoIndex.value = index + activeVideoIndex.value = index } } - } catch (error) { - console.error('加载章节详情失败:', error) } } diff --git a/pages/course/details/course.vue b/pages/course/details/course.vue index 3e78bc3..156b08d 100644 --- a/pages/course/details/course.vue +++ b/pages/course/details/course.vue @@ -259,60 +259,47 @@ onLoad(async (options: any) => { * 加载页面数据 */ const loadPageData = async () => { - try { - uni.showLoading({ title: '加载中...' }) + // 获取课程详情 + const res = await courseApi.getCourseDetail(courseId.value) + if (res.code === 0 && res.data) { + courseDetail.value = res.data.course + catalogueList.value = res.data.catalogues || [] + relatedBooks.value = res.data.shopProductList || [] - // 获取课程详情 - const res = await courseApi.getCourseDetail(courseId.value) - if (res.code === 0 && res.data) { - courseDetail.value = res.data.course - catalogueList.value = res.data.catalogues || [] - relatedBooks.value = res.data.shopProductList || [] - - // 计算学习进度 - if (catalogueList.value.length > 0) { - const totalProgress = catalogueList.value.reduce((sum, cat) => sum + cat.completion, 0) - learningProgress.value = Number((totalProgress / catalogueList.value.length).toFixed(2)) - } - - // 默认选择第一个目录 - if (catalogueList.value.length > 0) { - await switchCatalogue(0) - } + // 计算学习进度 + if (catalogueList.value.length > 0) { + const totalProgress = catalogueList.value.reduce((sum, cat) => sum + cat.completion, 0) + learningProgress.value = Number((totalProgress / catalogueList.value.length).toFixed(2)) } - // 检查VIP权益 - await checkVipStatus() - - // 加载评论 - await loadComments() - - } catch (error) { - console.error('加载页面数据失败:', error) - } finally { - uni.hideLoading() + // 默认选择第一个目录 + if (catalogueList.value.length > 0) { + await switchCatalogue(0) + } } + + // 检查VIP权益 + await checkVipStatus() + + // 加载评论 + await loadComments() } /** * 检查VIP状态 */ const checkVipStatus = async () => { - try { - const res = await courseApi.checkCourseVip(courseId.value) - if (res.code === 0) { - userVip.value = res.userVip || null - - // 如果不是VIP,获取需要的VIP类型 - if (!userVip.value) { - const moduleRes = await courseApi.getCourseVipModule(courseId.value) - if (moduleRes.code === 0) { - vipModuleList.value = moduleRes.list || [] - } + const res = await courseApi.checkCourseVip(courseId.value) + if (res.code === 0) { + userVip.value = res.userVip || null + + // 如果不是VIP,获取需要的VIP类型 + if (!userVip.value) { + const moduleRes = await courseApi.getCourseVipModule(courseId.value) + if (moduleRes.code === 0) { + vipModuleList.value = moduleRes.list || [] } } - } catch (error) { - console.error('检查VIP状态失败:', error) } } @@ -324,21 +311,17 @@ const switchCatalogue = async (index: number) => { const catalogue = catalogueList.value[index] // 获取章节列表 - try { - const res = await courseApi.getCatalogueChapterList(catalogue.id) - if (res.code === 0) { - chapterList.value = res.chapterList || [] - } - - // 检查是否支持复读 - if (catalogue.isBuy === 0 && !userVip.value) { - const renewRes = await courseApi.checkRenewPayment(catalogue.id) - showRenewBtn.value = renewRes.canRelearn || false - } else { - showRenewBtn.value = false - } - } catch (error) { - console.error('切换目录失败:', error) + const res = await courseApi.getCatalogueChapterList(catalogue.id) + if (res.code === 0) { + chapterList.value = res.chapterList || [] + } + + // 检查是否支持复读 + if (catalogue.isBuy === 0 && !userVip.value) { + const renewRes = await courseApi.checkRenewPayment(catalogue.id) + showRenewBtn.value = renewRes.canRelearn || false + } else { + showRenewBtn.value = false } } @@ -366,18 +349,12 @@ const handleChapterClick = (chapter: IChapter) => { const handleGetFreeCourse = async () => { if (!currentCatalogue.value) return - try { - uni.showLoading({ title: '领取中...' }) - const res = await courseApi.startStudyForMF(currentCatalogue.value.id) - if (res.code === 0) { - uni.showToast({ title: '领取成功', icon: 'success' }) - // 刷新页面数据 - await loadPageData() - } - } catch (error) { - console.error('领取免费课程失败:', error) - } finally { - uni.hideLoading() + uni.showLoading({ title: '领取中...' }) + const res = await courseApi.startStudyForMF(currentCatalogue.value.id) + if (res.code === 0) { + uni.showToast({ title: '领取成功', icon: 'success' }) + // 刷新页面数据 + await loadPageData() } } @@ -387,17 +364,13 @@ const handleGetFreeCourse = async () => { const handlePurchase = async () => { if (!currentCatalogue.value) return - try { - isFudu.value = false - const res = await courseApi.getProductListForCourse(currentCatalogue.value.id) - if (res.code === 0 && res.productList.length > 0) { - goodsList.value = res.productList - showGoodsSelector.value = true - } else { - uni.showToast({ title: '此课程暂无购买方式', icon: 'none' }) - } - } catch (error) { - console.error('获取商品列表失败:', error) + isFudu.value = false + const res = await courseApi.getProductListForCourse(currentCatalogue.value.id) + if (res.code === 0 && res.productList.length > 0) { + goodsList.value = res.productList + showGoodsSelector.value = true + } else { + uni.showToast({ title: '此课程暂无购买方式', icon: 'none' }) } } @@ -407,18 +380,14 @@ const handlePurchase = async () => { const handleRenew = async () => { if (!currentCatalogue.value) return - try { - isFudu.value = true - fuduCatalogueId.value = currentCatalogue.value.id - const res = await courseApi.getRenewProductList(currentCatalogue.value.id) - if (res.code === 0 && res.productList.length > 0) { - goodsList.value = res.productList - showGoodsSelector.value = true - } else { - uni.showToast({ title: '暂无复读方案', icon: 'none' }) - } - } catch (error) { - console.error('获取复读商品列表失败:', error) + isFudu.value = true + fuduCatalogueId.value = currentCatalogue.value.id + const res = await courseApi.getRenewProductList(currentCatalogue.value.id) + if (res.code === 0 && res.productList.length > 0) { + goodsList.value = res.productList + showGoodsSelector.value = true + } else { + uni.showToast({ title: '暂无复读方案', icon: 'none' }) } } diff --git a/pages/course/index.vue b/pages/course/index.vue index ce78c9b..44e1348 100644 --- a/pages/course/index.vue +++ b/pages/course/index.vue @@ -257,29 +257,25 @@ const handleFirstLevelClick = (item: string) => { * 获取课程分类数据 */ const getMedicalTags = async () => { - try { - const res = await courseSubjectClassificationApi.getCourseMedicalTree() - if (res && res.code === 0) { - if (res.labels && res.labels.length > 0) { - curseTagList.value = res.labels - // 根据 currentIndex 设置初始选中的分类 - if (res.labels[currentIndex.value]) { - const selectedTag = res.labels[currentIndex.value] - if (selectedTag.isLast === 0) { - // 非终极分类,显示子分类 - if (selectedTag.children && selectedTag.children.length > 0) { - sbuMedicalTagsList.value = selectedTag.children - } else { - sbuMedicalTagsList.value = [] - } + const res = await courseSubjectClassificationApi.getCourseMedicalTree() + if (res && res.code === 0) { + if (res.labels && res.labels.length > 0) { + curseTagList.value = res.labels + // 根据 currentIndex 设置初始选中的分类 + if (res.labels[currentIndex.value]) { + const selectedTag = res.labels[currentIndex.value] + if (selectedTag.isLast === 0) { + // 非终极分类,显示子分类 + if (selectedTag.children && selectedTag.children.length > 0) { + sbuMedicalTagsList.value = selectedTag.children + } else { + sbuMedicalTagsList.value = [] } } - } else { - curseTagList.value = [] } + } else { + curseTagList.value = [] } - } catch (error) { - console.error('获取医学课程分类失败:', error) } } /** @@ -309,13 +305,9 @@ const curseClick = (item: IMedicalTag, index: number) => { */ const soulCateList = ref([]) const getSoulCateList = async () => { - try { - const res = await courseSubjectClassificationApi.getCourseSoulTree() - if (res.labels&&res.labels.length>0) { - soulCateList.value = res.labels; - } - } catch (error) { - console.error('获取心理学课程分类失败:', error) + const res = await courseSubjectClassificationApi.getCourseSoulTree() + if (res.labels&&res.labels.length>0) { + soulCateList.value = res.labels; } } @@ -325,13 +317,9 @@ const getSoulCateList = async () => { */ const sociologyCateList = ref([]) const getSociologyCateList = async () => { - try { - const res = await courseSubjectClassificationApi.getCourseSociologyTree() - if (res.labels&&res.labels.length>0) { - sociologyCateList.value = res.labels; - } - } catch (error) { - console.error('获取国学课程分类失败:', error) + const res = await courseSubjectClassificationApi.getCourseSociologyTree() + if (res.labels&&res.labels.length>0) { + sociologyCateList.value = res.labels; } } @@ -369,17 +357,13 @@ const learnList = ref([]) // 观看记录列表 * 获取观看记录 */ const getLearnCourse = async () => { - try { - const res = await courseApi.getUserLateCourseList() - if (res && res.code === 0) { - if (res.page && res.page.length > 0) { - learnList.value = res.page - } else { - learnList.value = [] - } + const res = await courseApi.getUserLateCourseList() + if (res && res.code === 0) { + if (res.page && res.page.length > 0) { + learnList.value = res.page + } else { + learnList.value = [] } - } catch (error) { - console.error('获取观看记录失败:', error) } } @@ -389,17 +373,13 @@ const newsList = ref([]) // 新闻列表 * 获取新闻列表 */ const getNewsList = async () => { - try { - const res = await commonApi.getMessageList(0, 1, 0) - if (res && res.code === 0) { - if (res.messages && res.messages.length > 0) { - newsList.value = res.messages - } else { - newsList.value = [] - } + const res = await commonApi.getMessageList(0, 1, 0) + if (res && res.code === 0) { + if (res.messages && res.messages.length > 0) { + newsList.value = res.messages + } else { + newsList.value = [] } - } catch (error) { - console.error('获取新闻列表失败:', error) } } /** @@ -423,21 +403,17 @@ const tryListenList = ref([]) // 试听课程列表 * 获取试听课程列表 */ const getTryListenList = async () => { - try { - const res = await courseApi.getMarketCourseList({ - page: 1, - limit: 6, - id: 1 - }) - if (res && res.code === 0) { - if (res.courseList && res.courseList.records && res.courseList.records.length > 0) { - tryListenList.value = res.courseList.records - } else { - tryListenList.value = [] - } + const res = await courseApi.getMarketCourseList({ + page: 1, + limit: 6, + id: 1 + }) + if (res && res.code === 0) { + if (res.courseList && res.courseList.records && res.courseList.records.length > 0) { + tryListenList.value = res.courseList.records + } else { + tryListenList.value = [] } - } catch (error) { - console.error('获取试听课程失败:', error) } } diff --git a/pages/course/list/category.vue b/pages/course/list/category.vue index f7f2728..f547157 100644 --- a/pages/course/list/category.vue +++ b/pages/course/list/category.vue @@ -52,30 +52,26 @@ const subCategoryList = ref([]) // 子级分类列表 * 获取分类下的子级分类 */ const getSubCategoryList = async () => { - try { - let res: any = null - switch (subject.value) { - case '医学': - res = await courseSubjectClassificationApi.getCourseMedicalChildLabels(categoryId.value) - break - case '心理学': - res = await courseSubjectClassificationApi.getCourseSoulChildLabels(categoryId.value) - break + let res: any = null + switch (subject.value) { + case '医学': + res = await courseSubjectClassificationApi.getCourseMedicalChildLabels(categoryId.value) + break + case '心理学': + res = await courseSubjectClassificationApi.getCourseSoulChildLabels(categoryId.value) + break + } + if (res && res.code === 0) { + if (res.labels && res.labels.length > 0) { + subCategoryList.value = res.labels + // 默认选中第一个tab + tab_category_id.value = res.labels[0].id + radio_category_id.value = res.labels[0].children[0] && res.labels[0].children[0].id || 0 + } else { + subCategoryList.value = [] + tab_category_id.value = 0 + radio_category_id.value = 0 } - if (res && res.code === 0) { - if (res.labels && res.labels.length > 0) { - subCategoryList.value = res.labels - // 默认选中第一个tab - tab_category_id.value = res.labels[0].id - radio_category_id.value = res.labels[0].children[0] && res.labels[0].children[0].id || 0 - } else { - subCategoryList.value = [] - tab_category_id.value = 0 - radio_category_id.value = 0 - } - } - } catch (error) { - console.error('获取分类下的子级分类失败:', error) } } diff --git a/pages/login/forget.vue b/pages/login/forget.vue index e91fa68..7097bdf 100644 --- a/pages/login/forget.vue +++ b/pages/login/forget.vue @@ -191,16 +191,12 @@ const getCode = async () => { if (!isEmailEmpty()) return if (!isEmailVerified(email.value)) return - try { - await commonApi.sendMailCaptcha(email.value) - uni.showToast({ - title: t('login.sendCodeSuccess'), - icon: 'none' - }) - getCodeState() - } catch (error) { - console.error('Send code error:', error) - } + await commonApi.sendMailCaptcha(email.value) + uni.showToast({ + title: t('login.sendCodeSuccess'), + icon: 'none' + }) + getCodeState() } /** @@ -264,20 +260,16 @@ const onSubmit = async () => { if (!isConfirmPasswordEmpty()) return if (!isPasswordMatch()) return - try { - await resetPassword(email.value, code.value, password.value) + await resetPassword(email.value, code.value, password.value) - uni.showModal({ - title: t('global.tips'), - content: t('forget.passwordChanged'), - showCancel: false, - success: () => { - uni.navigateBack() - } - }) - } catch (error) { - console.error('Reset password error:', error) - } + uni.showModal({ + title: t('global.tips'), + content: t('forget.passwordChanged'), + showCancel: false, + success: () => { + uni.navigateBack() + } + }) } diff --git a/pages/login/login.vue b/pages/login/login.vue index 9eca8a8..b2ea834 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -285,13 +285,8 @@ const verifyCodeLogin = async () => { if (!isCodeEmpty()) return false - try { - const res = await loginWithCode(email.value, code.value) - return res - } catch (error) { - console.error('验证码登录失败:', error) - return null - } + const res = await loginWithCode(email.value, code.value) + return res || null } // 密码登录 const passwordLogin = async () => { @@ -301,13 +296,8 @@ const passwordLogin = async () => { if (!isPasswordEmpty()) return false - try { - const res = await loginWithPassword(phoneEmail.value, password.value) - return res - } catch (error) { - console.error('密码登录失败:', error) - return null - } + const res = await loginWithPassword(phoneEmail.value, password.value) + return res || null } // 提交登录 const onSubmit = async () => { diff --git a/pages/order/goodsConfirm.vue b/pages/order/goodsConfirm.vue index 79ad491..1997420 100644 --- a/pages/order/goodsConfirm.vue +++ b/pages/order/goodsConfirm.vue @@ -61,14 +61,8 @@ import GoodsPrice from '@/components/order/GoodsPrice.vue'; */ const userInfo = ref({}) const getUserInfo = async () => { - try { - const res = await orderApi.getUserInfo() - if (res.code === 0) { - userInfo.value = res.result || {} - } - } catch (error) { - console.error('获取用户信息失败:', error) - } + const res = await orderApi.getUserInfo() + userInfo.value = res.result || {} } /** @@ -77,15 +71,11 @@ const getUserInfo = async () => { const goodsIds = ref('') const goodsList = ref([]) const getGoodsList = async () => { - try { - // 获取商品详情 - const res = await orderApi.getShopProductListByIds(goodsIds.value) - - if (res.code === 0 && res.shopProductList?.length > 0) { - goodsList.value = res.shopProductList - } - } catch (error) { - console.error('获取商品列表失败:', error) + // 获取商品详情 + const res = await orderApi.getShopProductListByIds(goodsIds.value) + + if (res.shopProductList?.length > 0) { + goodsList.value = res.shopProductList } } diff --git a/pages/user/index.vue b/pages/user/index.vue index 7d62141..17ed04a 100644 --- a/pages/user/index.vue +++ b/pages/user/index.vue @@ -147,21 +147,17 @@ * 获取数据 */ const getData = async () => { - try { - // 获取用户信息 - const userRes = await getUserInfo() - console.log(userRes); - if (userRes.user) { - userStore.setUserInfo(userRes.user) - } + // 获取用户信息 + const userRes = await getUserInfo() + console.log(userRes); + if (userRes.user) { + userStore.setUserInfo(userRes.user) + } - // 获取VIP信息 - const vipRes = await getVipInfo() - if (vipRes.vipInfo) { - vipInfo.value = vipRes.vipInfo - } - } catch (error) { - console.error('获取数据失败:', error) + // 获取VIP信息 + const vipRes = await getVipInfo() + if (vipRes.vipInfo) { + vipInfo.value = vipRes.vipInfo } } diff --git a/pages/user/profile/index.vue b/pages/user/profile/index.vue index 4219762..6ca570c 100644 --- a/pages/user/profile/index.vue +++ b/pages/user/profile/index.vue @@ -199,14 +199,10 @@ const avatarUrl = ref('') */ const userInfo = ref({}) // 用户信息 const getData = async () => { - try { - const res = await getUserInfo() - if (res.result) { - userStore.setUserInfo(res.result) - userInfo.value = res.result - } - } catch (error) { - console.error('获取用户信息失败:', error) + const res = await getUserInfo() + if (res.result) { + userStore.setUserInfo(res.result) + userInfo.value = res.result } } @@ -324,16 +320,12 @@ const sendCode = async () => { return } - try { - await sendEmailCode(editForm.value.email) - uni.showToast({ - title: t('user.sendCodeSuccess'), - icon: 'none' - }) - startCountdown() - } catch (error) { - console.error('发送验证码失败:', error) - } + await sendEmailCode(editForm.value.email) + uni.showToast({ + title: t('user.sendCodeSuccess'), + icon: 'none' + }) + startCountdown() } /** @@ -398,92 +390,88 @@ const checkPasswordStrength = () => { const handleSubmit = async () => { const key = currentField.value?.key - try { - // 构建更新数据对象 - let updateData: any = Object.assign({}, userInfo.value) + // 构建更新数据对象 + let updateData: any = Object.assign({}, userInfo.value) - switch (key) { - case 'email': - // 更新邮箱 - if (!editForm.value.email || !editForm.value.code) { - uni.showToast({ - title: t('user.pleaseInputCode'), - icon: 'none' - }) - return - } - await updateEmail(userInfo.value.id, editForm.value.email, editForm.value.code) - break - - case 'password': - // 更新密码 - if (!passwordOk.value) { - uni.showToast({ - title: passwordNote.value, - icon: 'none' - }) - return - } - if (editForm.value.password !== editForm.value.confirmPassword) { - uni.showToast({ - title: t('user.passwordNotMatch'), - icon: 'none' - }) - return - } - await updatePassword(userInfo.value.id, editForm.value.password) - break - - case 'avatar': - // 更新头像 - console.log('avatarUrl.value:', avatarUrl.value) - if (!avatarUrl.value) { - uni.showToast({ - title: t('common.pleaseSelect') + t('user.avatar'), - icon: 'none' - }) - return - } - - // 如果是新上传的图片,需要先上传 - updateData.avatar = avatarUrl.value - await updateUserInfo(updateData) - break - - case 'sex': - // 更新性别 - updateData.sex = editValue.value - await updateUserInfo(updateData) - break - - default: - // 更新其他字段 - if (!editValue.value) { - uni.showToast({ - title: getPlaceholder(key), - icon: 'none' - }) - return - } - updateData[key] = editValue.value - await updateUserInfo(updateData) - break - } - - uni.showToast({ - title: t('user.updateSuccess'), - icon: 'success' - }) - - closeModal() - - // 刷新数据 - setTimeout(() => { - getData() - }, 500) - } catch (error) { - console.error('更新失败:', error) + switch (key) { + case 'email': + // 更新邮箱 + if (!editForm.value.email || !editForm.value.code) { + uni.showToast({ + title: t('user.pleaseInputCode'), + icon: 'none' + }) + return + } + await updateEmail(userInfo.value.id, editForm.value.email, editForm.value.code) + break + + case 'password': + // 更新密码 + if (!passwordOk.value) { + uni.showToast({ + title: passwordNote.value, + icon: 'none' + }) + return + } + if (editForm.value.password !== editForm.value.confirmPassword) { + uni.showToast({ + title: t('user.passwordNotMatch'), + icon: 'none' + }) + return + } + await updatePassword(userInfo.value.id, editForm.value.password) + break + + case 'avatar': + // 更新头像 + console.log('avatarUrl.value:', avatarUrl.value) + if (!avatarUrl.value) { + uni.showToast({ + title: t('common.pleaseSelect') + t('user.avatar'), + icon: 'none' + }) + return + } + + // 如果是新上传的图片,需要先上传 + updateData.avatar = avatarUrl.value + await updateUserInfo(updateData) + break + + case 'sex': + // 更新性别 + updateData.sex = editValue.value + await updateUserInfo(updateData) + break + + default: + // 更新其他字段 + if (!editValue.value) { + uni.showToast({ + title: getPlaceholder(key), + icon: 'none' + }) + return + } + updateData[key] = editValue.value + await updateUserInfo(updateData) + break } + + uni.showToast({ + title: t('user.updateSuccess'), + icon: 'success' + }) + + closeModal() + + // 刷新数据 + setTimeout(() => { + getData() + }, 500) } /** diff --git a/pages/user/recharge/index.vue b/pages/user/recharge/index.vue index e5f2840..398b07f 100644 --- a/pages/user/recharge/index.vue +++ b/pages/user/recharge/index.vue @@ -1,9 +1,9 @@