diff --git a/src/api/auth.js b/src/api/auth.js
index ed425f5..a971571 100644
--- a/src/api/auth.js
+++ b/src/api/auth.js
@@ -5,6 +5,8 @@ export const authAPI = {
return post('/api/v0/auth/wechat-login', { code }, {
skipAuthRefresh: true,
retryOnAuthFailure: false,
+ handleAuthFailure: false,
+ silent: true,
...options
})
},
@@ -15,6 +17,7 @@ export const authAPI = {
}, {
skipAuthRefresh: true,
retryOnAuthFailure: false,
+ handleAuthFailure: false,
...options
})
},
diff --git a/src/api/config.js b/src/api/config.js
index 9b826c0..d6ce7e9 100644
--- a/src/api/config.js
+++ b/src/api/config.js
@@ -2,7 +2,7 @@ import { get } from '../utils/request'
export const configAPI = {
getConfig(key) {
- if (!key) return Promise.reject(new Error('Config key is required'))
+ if (!key) return Promise.reject(new Error('缺少配置项'))
return get(`/api/v0/config/${key}`)
},
}
diff --git a/src/api/courseTable.js b/src/api/courseTable.js
index 50e7b81..a11bc37 100644
--- a/src/api/courseTable.js
+++ b/src/api/courseTable.js
@@ -22,7 +22,7 @@ export const courseTableAPI = {
},
deleteSchedule(semester) {
- if (!semester) return Promise.reject(new Error('semester is required'))
+ if (!semester) return Promise.reject(new Error('缺少学期信息'))
return del(`/api/v0/coursetable/schedule?semester=${encodeURIComponent(semester)}`)
}
}
diff --git a/src/composables/useThemePage.js b/src/composables/useThemePage.js
index cfece95..cc62d7b 100644
--- a/src/composables/useThemePage.js
+++ b/src/composables/useThemePage.js
@@ -1,10 +1,5 @@
import { useThemeStore } from '../stores/theme'
export const useThemePage = () => {
- const themeStore = useThemeStore()
-
- // 主题跟随系统,系统切换会重载小程序,这里初始化一次即可。
- themeStore.initTheme()
-
- return themeStore
+ return useThemeStore()
}
diff --git a/src/pages/achieveprint/index.config.js b/src/pages/achieveprint/index.config.js
index 2f73b86..0ae14b0 100644
--- a/src/pages/achieveprint/index.config.js
+++ b/src/pages/achieveprint/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '成绩单打印',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/address/index.config.js b/src/pages/address/index.config.js
index 912f843..57dd29b 100644
--- a/src/pages/address/index.config.js
+++ b/src/pages/address/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '快递地址',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/calendar/index.config.js b/src/pages/calendar/index.config.js
index eed6658..ef0890c 100644
--- a/src/pages/calendar/index.config.js
+++ b/src/pages/calendar/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '校历',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/competition/index.config.js b/src/pages/competition/index.config.js
index 012f9d1..9ece4b7 100644
--- a/src/pages/competition/index.config.js
+++ b/src/pages/competition/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '竞赛',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/discover/index.config.js b/src/pages/discover/index.config.js
index 647b16d..1625519 100644
--- a/src/pages/discover/index.config.js
+++ b/src/pages/discover/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '发现',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/exchange/index.config.js b/src/pages/exchange/index.config.js
index 500edac..01f9d4b 100644
--- a/src/pages/exchange/index.config.js
+++ b/src/pages/exchange/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '交换生',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/failrate/index.config.js b/src/pages/failrate/index.config.js
index 428b2c5..8113651 100644
--- a/src/pages/failrate/index.config.js
+++ b/src/pages/failrate/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '挂科率',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/final-review/detail/index.config.js b/src/pages/final-review/detail/index.config.js
index c0373e5..1b49a08 100644
--- a/src/pages/final-review/detail/index.config.js
+++ b/src/pages/final-review/detail/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '项目详情',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/final-review/detail/index.vue b/src/pages/final-review/detail/index.vue
index 4186885..b0cfbc2 100644
--- a/src/pages/final-review/detail/index.vue
+++ b/src/pages/final-review/detail/index.vue
@@ -852,8 +852,8 @@ const loadQuestionDetail = async (index, shouldScroll = false) => {
const scrollToQuestion = () => {
try {
// 获取系统信息
- const systemInfo = Taro.getSystemInfoSync();
- const windowHeight = systemInfo.windowHeight || 667; // 默认值作为备用
+ const windowInfo = Taro.getWindowInfo();
+ const windowHeight = windowInfo.windowHeight || 667; // 默认值作为备用
// 创建选择器查询
const query = Taro.createSelectorQuery();
diff --git a/src/pages/final-review/index.config.js b/src/pages/final-review/index.config.js
index dd35c78..61aa958 100644
--- a/src/pages/final-review/index.config.js
+++ b/src/pages/final-review/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '期末复习',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/gotojw/index.config.js b/src/pages/gotojw/index.config.js
index a2289db..47bffc7 100644
--- a/src/pages/gotojw/index.config.js
+++ b/src/pages/gotojw/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '教务系统',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/gpa-calculator/index.config.js b/src/pages/gpa-calculator/index.config.js
index 6b99854..0af7d24 100644
--- a/src/pages/gpa-calculator/index.config.js
+++ b/src/pages/gpa-calculator/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '绩点计算',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/gpa-calculator/index.vue b/src/pages/gpa-calculator/index.vue
index 3e0cea3..c25e0a5 100644
--- a/src/pages/gpa-calculator/index.vue
+++ b/src/pages/gpa-calculator/index.vue
@@ -369,15 +369,17 @@
-
-
- {{ major.name }}
- {{ major.gpa }}
- {{ major.bonus }}
+
+
+
+ {{ major.name }}
+ {{ major.gpa }}
+ {{ major.bonus }}
+
@@ -915,7 +917,7 @@ const switchToLocalData = () => {
closeBackupModal()
Taro.showToast({
- title: '已切回本地数据',
+ title: '已切回本地',
icon: 'success'
})
}
@@ -1104,7 +1106,7 @@ const uploadCurrentLocalBackup = async () => {
await gpaAPI.createBackup(buildBackupPayload())
await loadBackupList()
Taro.showToast({
- title: '备份上传成功',
+ title: '上传成功',
icon: 'success'
})
} catch (error) {
@@ -1187,7 +1189,7 @@ const deleteBackupItem = async (backupId) => {
}
Taro.showToast({
- title: '备份已删除',
+ title: '已删除',
icon: 'success'
})
} catch (error) {
@@ -1233,7 +1235,7 @@ const restoreBackupItem = async (backupId, { overwriteLocal = false } = {}) => {
closeBackupModal()
Taro.showToast({
- title: overwriteLocal ? '已覆盖本地数据' : '已切换到备份',
+ title: overwriteLocal ? '已覆盖' : '已切换',
icon: 'success'
})
} catch (error) {
diff --git a/src/pages/graduation/index.config.js b/src/pages/graduation/index.config.js
index 2f76181..904879b 100644
--- a/src/pages/graduation/index.config.js
+++ b/src/pages/graduation/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '毕业条件',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/groupchat/index.config.js b/src/pages/groupchat/index.config.js
index a1a482a..f841bda 100644
--- a/src/pages/groupchat/index.config.js
+++ b/src/pages/groupchat/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '群聊推荐',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/groupchat/index.vue b/src/pages/groupchat/index.vue
index e819d90..b3b7a7f 100644
--- a/src/pages/groupchat/index.vue
+++ b/src/pages/groupchat/index.vue
@@ -116,7 +116,7 @@ const copyGroupId = async (groupId, groupName) => {
});
Taro.showToast({
- title: `${groupName} 群号已复制`,
+ title: '群号已复制',
icon: "success",
duration: 2000
});
diff --git a/src/pages/hero/index.config.js b/src/pages/hero/index.config.js
index 4f7232c..0dfe2b5 100644
--- a/src/pages/hero/index.config.js
+++ b/src/pages/hero/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '英雄榜',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/home/components/StudyTaskCard.vue b/src/pages/home/components/StudyTaskCard.vue
index cb1a905..1f77e49 100644
--- a/src/pages/home/components/StudyTaskCard.vue
+++ b/src/pages/home/components/StudyTaskCard.vue
@@ -809,7 +809,7 @@ const toggleTaskStatus = async (taskId) => {
await studyTaskStore.updateStudyTask(taskId, updateData);
Taro.showToast({
- title: "状态更新成功",
+ title: "已更新",
icon: "success",
duration: 1000,
});
diff --git a/src/pages/home/index.config.js b/src/pages/home/index.config.js
index 2dfe70e..c193013 100644
--- a/src/pages/home/index.config.js
+++ b/src/pages/home/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '首页',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/home/index.vue b/src/pages/home/index.vue
index e08c8b0..ac49a16 100644
--- a/src/pages/home/index.vue
+++ b/src/pages/home/index.vue
@@ -345,7 +345,7 @@ const saveOrder = () => {
const resetOrder = () => {
sortableCards.value = [...defaultCards]
Taro.showToast({
- title: '已恢复默认顺序',
+ title: '已恢复默认',
icon: 'success'
})
}
diff --git a/src/pages/login/index.config.js b/src/pages/login/index.config.js
index 522de3a..2aefb84 100644
--- a/src/pages/login/index.config.js
+++ b/src/pages/login/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '登录',
navigationBarBackgroundColor: '@navBgColor',
navigationBarTextStyle: '@navTxtStyle',
diff --git a/src/pages/major-transfer/index.config.js b/src/pages/major-transfer/index.config.js
index bccf9df..811bff8 100644
--- a/src/pages/major-transfer/index.config.js
+++ b/src/pages/major-transfer/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '转专业',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/major-transfer/index.vue b/src/pages/major-transfer/index.vue
index 94633ab..02262d1 100644
--- a/src/pages/major-transfer/index.vue
+++ b/src/pages/major-transfer/index.vue
@@ -711,7 +711,7 @@ const handleAttachmentTap = async (notice) => {
try {
await Taro.setClipboardData({ data: copyText })
Taro.showToast({
- title: '网址已复制成功',
+ title: '已复制',
icon: 'success',
duration: 2000,
})
@@ -1133,8 +1133,8 @@ const measureChartWidth = () => new Promise((resolve) => {
return
}
- const systemInfo = Taro.getSystemInfoSync()
- chartWidth.value = Math.max(280, Math.floor((systemInfo.windowWidth || 375) - 56))
+ const windowInfo = Taro.getWindowInfo()
+ chartWidth.value = Math.max(280, Math.floor((windowInfo.windowWidth || 375) - 56))
resolve(chartWidth.value)
})
})
diff --git a/src/pages/map/index.config.js b/src/pages/map/index.config.js
index bf96d59..727f94b 100644
--- a/src/pages/map/index.config.js
+++ b/src/pages/map/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '校园地图',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/materials/detail/index.config.js b/src/pages/materials/detail/index.config.js
index 7b91013..8d685b0 100644
--- a/src/pages/materials/detail/index.config.js
+++ b/src/pages/materials/detail/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '资料详情',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/materials/detail/index.vue b/src/pages/materials/detail/index.vue
index 0cbc2c6..69ae8a9 100644
--- a/src/pages/materials/detail/index.vue
+++ b/src/pages/materials/detail/index.vue
@@ -288,7 +288,7 @@ const openExternalLink = () => {
data: material.value.external_link,
success: () => {
Taro.showToast({
- title: '请到浏览器粘贴使用',
+ title: '已复制链接',
icon: 'success'
})
}
diff --git a/src/pages/materials/index.config.js b/src/pages/materials/index.config.js
index d6f8543..2dd8c97 100644
--- a/src/pages/materials/index.config.js
+++ b/src/pages/materials/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '资料库',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/notifications/detail/index.config.js b/src/pages/notifications/detail/index.config.js
index 81ea00f..c9ac4a8 100644
--- a/src/pages/notifications/detail/index.config.js
+++ b/src/pages/notifications/detail/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '信息详情',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/notifications/detail/index.vue b/src/pages/notifications/detail/index.vue
index 20af161..518e057 100644
--- a/src/pages/notifications/detail/index.vue
+++ b/src/pages/notifications/detail/index.vue
@@ -167,6 +167,7 @@ import { ref, computed, onMounted } from 'vue'
import Taro from '@tarojs/taro'
import { useNotificationStore } from '../../../stores/notifications'
import SkeletonDetail from '../../../components/SkeletonDetail.vue'
+import { safeNavigateBack } from '../../../utils/index'
const themeStore = useThemePage()
@@ -308,7 +309,7 @@ const formatDateTime = (dateString) => {
}
const goBack = () => {
- Taro.navigateBack()
+ safeNavigateBack('/pages/notifications/index')
}
Taro.useShareAppMessage((res) => {
diff --git a/src/pages/notifications/index.config.js b/src/pages/notifications/index.config.js
index 48465bb..d872dea 100644
--- a/src/pages/notifications/index.config.js
+++ b/src/pages/notifications/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '信息海洋',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/organization/detail/index.config.js b/src/pages/organization/detail/index.config.js
index a4f9df8..f9259dd 100644
--- a/src/pages/organization/detail/index.config.js
+++ b/src/pages/organization/detail/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '组织详情',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/organization/detail/index.vue b/src/pages/organization/detail/index.vue
index 9cdedee..d9f573f 100644
--- a/src/pages/organization/detail/index.vue
+++ b/src/pages/organization/detail/index.vue
@@ -74,6 +74,7 @@ import { useThemePage } from '../../../composables/useThemePage'
import { onMounted, ref } from 'vue'
import Taro from '@tarojs/taro'
import { organizationAPI } from '../../../api'
+import { safeNavigateBack } from '../../../utils/index'
const themeStore = useThemePage()
@@ -155,7 +156,7 @@ const copyContact = async () => {
}
const goBack = () => {
- Taro.navigateBack()
+ safeNavigateBack('/pages/organization/index')
}
onMounted(() => {
diff --git a/src/pages/organization/index.config.js b/src/pages/organization/index.config.js
index 9e82ff4..25a02dd 100644
--- a/src/pages/organization/index.config.js
+++ b/src/pages/organization/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '组织',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/points/index.config.js b/src/pages/points/index.config.js
index 7c86319..b9046d2 100644
--- a/src/pages/points/index.config.js
+++ b/src/pages/points/index.config.js
@@ -1,4 +1,3 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '我的积分'
}
diff --git a/src/pages/profile/index.config.js b/src/pages/profile/index.config.js
index 6721472..888ac17 100644
--- a/src/pages/profile/index.config.js
+++ b/src/pages/profile/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '我的',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/qualification/index.config.js b/src/pages/qualification/index.config.js
index 29e3bb7..017ac9f 100644
--- a/src/pages/qualification/index.config.js
+++ b/src/pages/qualification/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '考级考证',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/schedule/components/CourseDetailModal.vue b/src/pages/schedule/components/CourseDetailModal.vue
index 9d84352..649f4fe 100644
--- a/src/pages/schedule/components/CourseDetailModal.vue
+++ b/src/pages/schedule/components/CourseDetailModal.vue
@@ -170,7 +170,7 @@ ${currentCourse.value.class ? `班级:${currentCourse.value.class}` : ''}
data: info,
success: () => {
Taro.showToast({
- title: '已复制到剪贴板',
+ title: '已复制',
icon: 'success'
})
}
diff --git a/src/pages/schedule/index.config.js b/src/pages/schedule/index.config.js
index 094c94f..e4b590b 100644
--- a/src/pages/schedule/index.config.js
+++ b/src/pages/schedule/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '一起来学课程表',
enableShareAppMessage: true,
enableShareTimeline: true
diff --git a/src/pages/schedule/schedule-bind/index.config.js b/src/pages/schedule/schedule-bind/index.config.js
index 498a120..2796837 100644
--- a/src/pages/schedule/schedule-bind/index.config.js
+++ b/src/pages/schedule/schedule-bind/index.config.js
@@ -1,4 +1,3 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '绑定班级'
}
diff --git a/src/pages/schedule/schedule-bind/index.vue b/src/pages/schedule/schedule-bind/index.vue
index a60c3da..456c5bc 100644
--- a/src/pages/schedule/schedule-bind/index.vue
+++ b/src/pages/schedule/schedule-bind/index.vue
@@ -101,6 +101,7 @@ import Taro from '@tarojs/taro'
import { useScheduleStore } from '../../../stores/schedule'
import { useAuthStore } from '../../../stores/auth'
import { courseTableAPI } from '../../../api/index'
+import { safeNavigateBack } from '../../../utils/index'
const themeStore = useThemePage()
@@ -173,7 +174,7 @@ const handleSearch = () => {
const search = async () => {
if (!searchKeyword.value.trim()) {
Taro.showToast({
- title: '请输入班级名称',
+ title: '请输入班级',
icon: 'error'
})
return
@@ -262,7 +263,7 @@ const confirmBind = async () => {
setTimeout(() => {
// 传递消息通知课表页刷新
Taro.eventCenter.trigger('reloadSchedule')
- Taro.navigateBack()
+ safeNavigateBack('/pages/schedule/index', true)
}, 1000)
} catch (error) {
@@ -295,7 +296,7 @@ const handleResetSchedule = () => {
setTimeout(() => {
// 传递消息通知课表页刷新
Taro.eventCenter.trigger('reloadSchedule')
- Taro.navigateBack()
+ safeNavigateBack('/pages/schedule/index', true)
}, 1000)
} catch (error) {
diff --git a/src/pages/teacher-reviews/index.config.js b/src/pages/teacher-reviews/index.config.js
index b5d6951..89c05f9 100644
--- a/src/pages/teacher-reviews/index.config.js
+++ b/src/pages/teacher-reviews/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '选课助手',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/teacher-reviews/index.vue b/src/pages/teacher-reviews/index.vue
index 084b767..a23c85b 100644
--- a/src/pages/teacher-reviews/index.vue
+++ b/src/pages/teacher-reviews/index.vue
@@ -208,19 +208,11 @@
-
-
+
+
-
+
写评价
@@ -228,15 +220,15 @@
-
-
+
+
教师姓名
@@ -246,7 +238,7 @@
@@ -258,19 +250,13 @@
:range="campusOptions"
@change="onCampusChange"
>
-
+
{{ newReview.campus || "请选择校区" }}
-
+
@@ -283,18 +269,16 @@
v-for="attitude in attitudeOptions"
:key="attitude.value"
@tap="selectAttitude(attitude.value)"
- :class="[
- 'flex-1 rounded-md p-2 text-center',
- newReview.attitude === attitude.value
- ? attitude.value === REVIEW_ATTITUDES.RECOMMEND
- ? 'bg-success text-white border-success'
- : attitude.value === REVIEW_ATTITUDES.NEUTRAL
- ? 'bg-brand text-white border-brand'
- : attitude.value === REVIEW_ATTITUDES.AVOID
- ? 'bg-danger text-white border-danger'
- : 'bg-page text-fg-muted border-line'
- : 'bg-page text-fg-muted border-line',
- ]"
+ class="flex-1 py-2.5 rounded-lg border flex items-center justify-center gap-1.5 text-sm font-medium"
+ :class="newReview.attitude === attitude.value
+ ? attitude.value === REVIEW_ATTITUDES.RECOMMEND
+ ? 'bg-success text-white border-success'
+ : attitude.value === REVIEW_ATTITUDES.NEUTRAL
+ ? 'bg-brand text-white border-brand'
+ : attitude.value === REVIEW_ATTITUDES.AVOID
+ ? 'bg-danger text-white border-danger'
+ : 'bg-page text-fg-muted border-line'
+ : 'border-line text-fg-muted bg-surface'"
>
{{ attitude.label }}
@@ -307,34 +291,30 @@
- {{ newReview.content.length }}/500
+ {{ newReview.content.length }}/500
-
-
+
+
-
-
-
- 取消
-
-
- {{ submitting ? "提交中..." : "提交评价" }}
-
+
+
+ 取消
+
+
+ {{ submitting ? "提交中..." : "提交评价" }}
diff --git a/src/pages/terms-of-service/index.config.js b/src/pages/terms-of-service/index.config.js
index ff8e0af..43615cf 100644
--- a/src/pages/terms-of-service/index.config.js
+++ b/src/pages/terms-of-service/index.config.js
@@ -1,4 +1,3 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '用户协议'
}
diff --git a/src/pages/webview/index.config.js b/src/pages/webview/index.config.js
index 61fa8ec..f18096d 100644
--- a/src/pages/webview/index.config.js
+++ b/src/pages/webview/index.config.js
@@ -1,5 +1,4 @@
export default {
- enablePageMeta: true,
navigationBarTitleText: '江理一起来学',
backgroundColor: '@pageBgColor',
enableShareAppMessage: true,
diff --git a/src/pages/webview/index.vue b/src/pages/webview/index.vue
index e56a4c6..07027f5 100644
--- a/src/pages/webview/index.vue
+++ b/src/pages/webview/index.vue
@@ -38,7 +38,7 @@ onMounted(() => {
}
} else {
Taro.showToast({
- title: 'URL参数错误',
+ title: '参数错误',
icon: 'error'
})
}
diff --git a/src/stores/auth.js b/src/stores/auth.js
index 76d12ba..4e737e1 100644
--- a/src/stores/auth.js
+++ b/src/stores/auth.js
@@ -1,6 +1,7 @@
import { defineStore } from 'pinia'
import Taro from '@tarojs/taro'
import { authAPI, userAPI } from '../api'
+import { getSafeErrorMessage, isTechnicalErrorMessage } from '../utils/errorMessage'
const STORAGE_KEYS = {
token: 'token',
@@ -23,6 +24,17 @@ const normalizeTimestampToMs = (timestamp) => {
}
let ongoingRefreshPromise = null
+const DEFAULT_AUTH_EXPIRED_TITLE = '请重新登录'
+
+const normalizeExpireTokenTitle = (title) => {
+ const normalizedTitle = typeof title === 'string' ? title.trim() : ''
+
+ if (!normalizedTitle || isTechnicalErrorMessage(normalizedTitle)) {
+ return DEFAULT_AUTH_EXPIRED_TITLE
+ }
+
+ return normalizedTitle
+}
export const useAuthStore = defineStore('auth', {
state: () => ({
@@ -95,9 +107,11 @@ export const useAuthStore = defineStore('auth', {
} catch (error) {
console.error('微信登录失败:', error)
- Taro.showToast({
- title: error.message || '登录失败',
- icon: 'error'
+ await Taro.showModal({
+ title: '登录失败',
+ content: getSafeErrorMessage(error, '登录失败,请稍后重试'),
+ showCancel: false,
+ confirmText: '知道了'
})
throw error
@@ -267,10 +281,11 @@ export const useAuthStore = defineStore('auth', {
: options
const {
- title = '请重新登录',
+ title = DEFAULT_AUTH_EXPIRED_TITLE,
showToast = true,
navigate = true
} = normalizedOptions
+ const safeTitle = normalizeExpireTokenTitle(title)
if (!this.isLoggedIn && !this.token && !this.refreshToken) {
return
@@ -283,7 +298,7 @@ export const useAuthStore = defineStore('auth', {
if (showToast) {
Taro.showToast({
- title,
+ title: safeTitle,
icon: 'error'
})
}
diff --git a/src/stores/countdown.js b/src/stores/countdown.js
index 71aea04..cf33e8e 100644
--- a/src/stores/countdown.js
+++ b/src/stores/countdown.js
@@ -67,7 +67,7 @@ export const useCountdownStore = defineStore('countdown', {
this.isFetchData = true
return data
} catch (error) {
- this.error = error.message || '获取倒数日列表失败'
+ this.error = '获取倒数日列表失败,请稍后重试'
console.error('获取倒数日列表失败:', error)
throw error
} finally {
diff --git a/src/stores/study-tasks.js b/src/stores/study-tasks.js
index c4993d4..42ce39a 100644
--- a/src/stores/study-tasks.js
+++ b/src/stores/study-tasks.js
@@ -96,7 +96,7 @@ export const useStudyTaskStore = defineStore('studyTask', {
this.isFetchData = true
return data
} catch (error) {
- this.error = error.message || '获取学习任务列表失败'
+ this.error = '获取学习任务列表失败,请稍后重试'
console.error('获取学习任务列表失败:', error)
throw error
} finally {
diff --git a/src/stores/theme.js b/src/stores/theme.js
index 171dee4..262f7f5 100644
--- a/src/stores/theme.js
+++ b/src/stores/theme.js
@@ -25,18 +25,11 @@ const CSS_VAR_MAP = {
themeSkeletonTo: '--theme-skeleton-to'
}
-const TAB_ITEMS = [
- ['tabHomeIcon', 'tabHomeSelectedIcon'],
- ['tabScheduleIcon', 'tabScheduleSelectedIcon'],
- ['tabDiscoverIcon', 'tabDiscoverSelectedIcon'],
- ['tabProfileIcon', 'tabProfileSelectedIcon']
-]
-
const normalizeTheme = (theme) => theme === 'dark' ? 'dark' : 'light'
const getSystemTheme = () => {
try {
- return normalizeTheme(Taro.getSystemInfoSync()?.theme)
+ return normalizeTheme(Taro.getAppBaseInfo()?.theme)
} catch (error) {
console.warn('获取系统主题失败:', error)
return 'light'
@@ -82,15 +75,7 @@ export const useThemeStore = defineStore('theme', {
nativeTheme() {
return {
pageBg: this.tokens.pageBgColor,
- pageBgTop: this.tokens.pageBgColorTop,
- pageBgBottom: this.tokens.pageBgColorBottom,
- navBg: this.tokens.navBgColor,
- navFrontColor: this.tokens.navTxtStyle === 'white' ? '#ffffff' : '#000000',
- backgroundTextStyle: this.tokens.backgroundTextStyle,
- tabColor: this.tokens.tabFontColor,
- tabSelectedColor: this.tokens.tabSelectedColor,
- tabBg: this.tokens.tabBgColor,
- tabBorderStyle: this.tokens.tabBorderStyle
+ backgroundTextStyle: this.tokens.backgroundTextStyle
}
}
},
@@ -98,61 +83,6 @@ export const useThemeStore = defineStore('theme', {
actions: {
initTheme() {
this.systemTheme = getSystemTheme()
- this.applyNativeTheme()
- },
-
- applyNativeTheme() {
- const nativeTheme = this.nativeTheme
-
- try {
- Taro.setNavigationBarColor({
- frontColor: nativeTheme.navFrontColor,
- backgroundColor: nativeTheme.navBg
- })
- } catch (error) {
- console.warn('设置导航栏主题失败:', error)
- }
-
- try {
- Taro.setBackgroundColor({
- backgroundColor: nativeTheme.pageBg,
- backgroundColorTop: nativeTheme.pageBgTop,
- backgroundColorBottom: nativeTheme.pageBgBottom
- })
- } catch (error) {
- console.warn('设置页面背景主题失败:', error)
- }
-
- try {
- Taro.setBackgroundTextStyle({
- textStyle: nativeTheme.backgroundTextStyle
- })
- } catch (error) {
- console.warn('设置下拉背景文字主题失败:', error)
- }
-
- try {
- Taro.setTabBarStyle({
- color: nativeTheme.tabColor,
- selectedColor: nativeTheme.tabSelectedColor,
- backgroundColor: nativeTheme.tabBg,
- borderStyle: nativeTheme.tabBorderStyle
- })
- } catch (error) {
- console.warn('设置 tabBar 主题失败:', error)
- }
-
- TAB_ITEMS.forEach(([iconKey, selectedIconKey], index) => {
- try {
- Taro.setTabBarItem({
- index,
- iconPath: this.tokens[iconKey],
- selectedIconPath: this.tokens[selectedIconKey]
- })
- } catch (error) {
- console.warn(`设置 tabBar 第 ${index} 项图标失败:`, error)
- }
- })
}
}
})
diff --git a/src/utils/errorMessage.js b/src/utils/errorMessage.js
new file mode 100644
index 0000000..4ab85c5
--- /dev/null
+++ b/src/utils/errorMessage.js
@@ -0,0 +1,102 @@
+const DEFAULT_ERROR_MESSAGE = '操作失败,请稍后重试'
+const DEFAULT_REQUEST_ERROR_MESSAGE = '操作失败,请稍后重试'
+const AUTH_EXPIRED_MESSAGE = '请重新登录'
+
+const TECHNICAL_ERROR_PATTERN = /(refresh[_\s-]?token|access[_\s-]?token|id[_\s-]?token|token|jwt|bearer|authorization|unauthorized|forbidden|invalid\s+(refresh[_\s-]?token|access[_\s-]?token|id[_\s-]?token|token)|sql|database|exception|stack|traceback|typeerror|referenceerror|syntaxerror|rangeerror|json|parse|undefined|null|nan|http\s*\d{3}|status\s*code|internal server error|bad gateway|gateway timeout|service unavailable|taro_app_api_base_url|request url|config key|semester is required|微信登录code|登录code|响应数据异常|数据格式异常|数据解析失败|刷新令牌|访问令牌|令牌|服务器内部错误)/i
+const NETWORK_ERROR_PATTERN = /(request:fail|network|timeout|timed out|socket|econn|enotfound|eai_again|failed to fetch|offline)/i
+const GENERIC_RAW_ERROR_PATTERN = /^(请求失败|网络错误|操作失败)$/
+
+const normalizeMessage = (message) => {
+ return typeof message === 'string' ? message.trim() : ''
+}
+
+export const getRawErrorMessage = (error) => {
+ if (typeof error === 'string') {
+ return normalizeMessage(error)
+ }
+
+ return normalizeMessage(error?.message || error?.errMsg || error?.statusMessage)
+}
+
+export const isTechnicalErrorMessage = (message) => {
+ const normalizedMessage = normalizeMessage(message)
+
+ if (!normalizedMessage) {
+ return false
+ }
+
+ return normalizedMessage.length > 120 ||
+ normalizedMessage.includes('\n') ||
+ TECHNICAL_ERROR_PATTERN.test(normalizedMessage)
+}
+
+export const getSafeErrorMessage = (error, fallbackMessage = DEFAULT_ERROR_MESSAGE) => {
+ const rawMessage = getRawErrorMessage(error)
+
+ if (!rawMessage || GENERIC_RAW_ERROR_PATTERN.test(rawMessage) || isTechnicalErrorMessage(rawMessage)) {
+ return fallbackMessage
+ }
+
+ return rawMessage
+}
+
+const getHttpStatusCode = (error) => {
+ const statusCode = Number(error?.httpStatusCode)
+ return Number.isFinite(statusCode) && statusCode > 0 ? statusCode : null
+}
+
+const getRequestFallbackMessage = (error, fallbackMessage = DEFAULT_REQUEST_ERROR_MESSAGE) => {
+ const rawMessage = getRawErrorMessage(error)
+ const httpStatusCode = getHttpStatusCode(error)
+
+ if (error?.isAuthError || httpStatusCode === 401) {
+ return AUTH_EXPIRED_MESSAGE
+ }
+
+ if (NETWORK_ERROR_PATTERN.test(rawMessage)) {
+ return rawMessage.toLowerCase().includes('timeout')
+ ? '网络请求超时,请稍后重试'
+ : '网络异常,请检查网络后重试'
+ }
+
+ if (httpStatusCode === 403) {
+ return '暂无操作权限'
+ }
+
+ if (httpStatusCode === 404) {
+ return '请求的内容不存在'
+ }
+
+ if (httpStatusCode === 429) {
+ return '操作太频繁,请稍后再试'
+ }
+
+ if (httpStatusCode >= 500) {
+ return '服务暂时不可用,请稍后重试'
+ }
+
+ return fallbackMessage
+}
+
+const shouldForceRequestFallback = (error) => {
+ const rawMessage = getRawErrorMessage(error)
+ const httpStatusCode = getHttpStatusCode(error)
+
+ return Boolean(error?.isAuthError) ||
+ NETWORK_ERROR_PATTERN.test(rawMessage) ||
+ httpStatusCode === 401 ||
+ httpStatusCode === 403 ||
+ httpStatusCode === 404 ||
+ httpStatusCode === 429 ||
+ httpStatusCode >= 500
+}
+
+export const getSafeRequestErrorMessage = (error, fallbackMessage = DEFAULT_REQUEST_ERROR_MESSAGE) => {
+ const safeFallbackMessage = getRequestFallbackMessage(error, fallbackMessage)
+
+ if (shouldForceRequestFallback(error)) {
+ return safeFallbackMessage
+ }
+
+ return getSafeErrorMessage(error, safeFallbackMessage)
+}
diff --git a/src/utils/image.js b/src/utils/image.js
index 85befee..80e5fe0 100644
--- a/src/utils/image.js
+++ b/src/utils/image.js
@@ -339,7 +339,7 @@ export async function getSignedImageUrl(uri, expireSeconds = 600, useCache = tru
return signed_url
} catch (error) {
console.error('获取图片签名URL失败:', error)
- throw new Error(`获取图片签名失败: ${error.message}`)
+ throw new Error('获取图片签名失败')
}
}
diff --git a/src/utils/index.js b/src/utils/index.js
index f127751..4efb6d7 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -1,5 +1,6 @@
import { REVIEW_ATTITUDES, REVIEW_STATUS, USER_ROLES } from './constants'
import { formatDateTime } from './time'
+import Taro from '@tarojs/taro'
// 导出图片相关工具方法
export {
@@ -12,6 +13,22 @@ export {
cleanExpiredLocalCache
} from './image'
+/**
+ * 安全返回:导航栈 > 1 时正常返回,否则跳转到 fallback 页面
+ * @param {string} fallbackUrl - 无法返回时的跳转路径
+ * @param {boolean} isTab - fallback 是否为 TabBar 页面
+ */
+export const safeNavigateBack = (fallbackUrl, isTab = false) => {
+ const pages = Taro.getCurrentPages()
+ if (pages.length > 1) {
+ Taro.navigateBack()
+ } else if (isTab) {
+ Taro.switchTab({ url: fallbackUrl })
+ } else {
+ Taro.redirectTo({ url: fallbackUrl })
+ }
+}
+
/**
* 格式化日期
* @param {string|Date} dateString
diff --git a/src/utils/request.js b/src/utils/request.js
index fd89585..453820e 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -1,6 +1,7 @@
/* global API_BASE_URL */
import Taro from '@tarojs/taro'
import { useAuthStore } from '../stores/auth'
+import { getSafeRequestErrorMessage } from './errorMessage'
// API基础配置
const BASE_URL = API_BASE_URL.replace(/\/$/, '')
@@ -145,24 +146,24 @@ const createRequestError = (message, extra = {}) => {
}
let isRequestErrorModalVisible = false
-let queuedRequestErrorMessage = null
+let queuedRequestError = null
const buildRequestErrorContent = (error) => {
- const message = error?.message || error?.errMsg || '网络错误'
+ const message = getSafeRequestErrorMessage(error)
const requestId = error?.requestId
if (!requestId) {
return message
}
- return `${message}\n\n请求ID: ${requestId}`
+ return `${message}\n\n问题编号:${requestId}`
}
const showRequestErrorModal = async (error) => {
const content = buildRequestErrorContent(error)
if (isRequestErrorModalVisible) {
- queuedRequestErrorMessage = content
+ queuedRequestError = error
return
}
@@ -170,7 +171,7 @@ const showRequestErrorModal = async (error) => {
try {
await Taro.showModal({
- title: '请求失败',
+ title: '操作失败',
content,
showCancel: false,
confirmText: '知道了'
@@ -178,12 +179,15 @@ const showRequestErrorModal = async (error) => {
} finally {
isRequestErrorModalVisible = false
- if (queuedRequestErrorMessage && queuedRequestErrorMessage !== content) {
- const nextMessage = queuedRequestErrorMessage
- queuedRequestErrorMessage = null
- await showRequestErrorModal({ message: nextMessage })
+ if (queuedRequestError) {
+ const nextError = queuedRequestError
+ queuedRequestError = null
+
+ if (buildRequestErrorContent(nextError) !== content) {
+ await showRequestErrorModal(nextError)
+ }
} else {
- queuedRequestErrorMessage = null
+ queuedRequestError = null
}
}
}
@@ -417,8 +421,10 @@ export const request = async (options) => {
}
}
- if (finalError?.isAuthError && handleAuthFailure) {
- useAuthStore().expireToken(finalError.message || '请重新登录')
+ if (finalError?.isAuthError) {
+ if (handleAuthFailure) {
+ useAuthStore().expireToken()
+ }
} else if (!silent) {
await showRequestErrorModal(finalError)
}