diff --git a/schoolNewsWeb/src/types/enums/achievement-enums.ts b/schoolNewsWeb/src/types/enums/achievement-enums.ts index 79e928e..3cb291e 100644 --- a/schoolNewsWeb/src/types/enums/achievement-enums.ts +++ b/schoolNewsWeb/src/types/enums/achievement-enums.ts @@ -159,7 +159,7 @@ export class AchievementEnumHelper { switch (conditionType) { case AchievementConditionType.LEARNING_TIME: - return `${typeDesc}达到${conditionValue}分钟`; + return `${typeDesc}达到${conditionValue/60}分钟`; case AchievementConditionType.RESOURCE_VIEW_COUNT: return `${typeDesc}达到${conditionValue}个`; case AchievementConditionType.COURSE_COMPLETE_COUNT: diff --git a/schoolNewsWeb/src/utils/iconUtils.ts b/schoolNewsWeb/src/utils/iconUtils.ts new file mode 100644 index 0000000..d2180fc --- /dev/null +++ b/schoolNewsWeb/src/utils/iconUtils.ts @@ -0,0 +1,67 @@ +/** + * @description 图标路径处理工具 + * @author yslg + * @since 2025-10-27 + */ + +import { PUBLIC_IMG_PATH } from '@/config'; + +/** + * 获取图标完整路径 + * @param icon 图标路径或URL + * @param subPath 子路径(可选,默认为 achievement) + * @returns 完整的图标URL + * + * @example + * // 仅文件名 + * getIconUrl('v1-icon.svg') // => '/schoolNewsWeb/img/achievement/v1-icon.svg' + * + * // 完整相对路径 + * getIconUrl('/img/achievement/v1-icon.svg') // => '/schoolNewsWeb/img/achievement/v1-icon.svg' + * + * // 外部URL + * getIconUrl('https://cdn.com/icon.svg') // => 'https://cdn.com/icon.svg' + */ +export function getIconUrl(icon?: string, subPath = 'achievement'): string { + if (!icon) return ''; + + // 如果是http或https开头,直接返回(外部URL) + if (icon.startsWith('http://') || icon.startsWith('https://')) { + return icon; + } + + // 如果已经包含完整路径(带 schoolNewsWeb 前缀) + if (icon.startsWith('/schoolNewsWeb/')) { + return icon; + } + + // 如果包含 /img/ 路径,拼接 schoolNewsWeb 前缀 + if (icon.startsWith('/img/') || icon.startsWith('img/')) { + const normalizedPath = icon.startsWith('/') ? icon : `/${icon}`; + return `/schoolNewsWeb${normalizedPath}`; + } + + // 否则拼接默认路径 + const fullPath = `${PUBLIC_IMG_PATH}/${subPath}`; + return icon.startsWith('/') ? `${fullPath}${icon}` : `${fullPath}/${icon}`; +} + +/** + * 获取成就图标URL + * @param icon 图标路径或文件名 + * @returns 完整的成就图标URL + */ +export function getAchievementIconUrl(icon?: string): string { + return getIconUrl(icon, 'achievement'); +} + +/** + * 根据等级获取等级图标URL + * @param level 等级(1-6) + * @returns 等级图标URL + */ +export function getLevelIconUrl(level = 1): string { + const validLevel = Math.max(1, Math.min(6, level)); // 限制在1-6之间 + return getIconUrl(`v${validLevel}-icon.svg`, 'achievement'); +} + diff --git a/schoolNewsWeb/src/views/admin/manage/achievement/AchievementManagementView.vue b/schoolNewsWeb/src/views/admin/manage/achievement/AchievementManagementView.vue index ef976b2..615b54c 100644 --- a/schoolNewsWeb/src/views/admin/manage/achievement/AchievementManagementView.vue +++ b/schoolNewsWeb/src/views/admin/manage/achievement/AchievementManagementView.vue @@ -315,7 +315,7 @@ import { Plus, Picture } from '@element-plus/icons-vue'; import { achievementApi } from '@/apis/achievement'; import type { Achievement, UserAchievement } from '@/types'; import { AchievementEnumHelper } from '@/types/enums/achievement-enums'; -import { PUBLIC_IMG_PATH } from '@/config'; +import { getAchievementIconUrl } from '@/utils/iconUtils'; // 响应式数据 const loading = ref(false); @@ -393,17 +393,7 @@ function formatConditionValue(conditionType?: number, conditionValue?: number): } // 获取图标完整路径 -function getIconUrl(icon?: string): string { - if (!icon) return ''; - // 如果是http或https开头,直接返回 - if (icon.startsWith('http://') || icon.startsWith('https://')) { - return icon; - } - - // 否则拼接默认成就图标路径 - const path = `${PUBLIC_IMG_PATH}/achievement`; - return icon.startsWith('/') ? `${path}${icon}` : `${path}/${icon}`; -} +const getIconUrl = getAchievementIconUrl; // 加载成就列表 async function loadAchievementList() { diff --git a/schoolNewsWeb/src/views/admin/manage/crontab/NewsCrawlerView.vue b/schoolNewsWeb/src/views/admin/manage/crontab/NewsCrawlerView.vue index a5e696a..5ee324a 100644 --- a/schoolNewsWeb/src/views/admin/manage/crontab/NewsCrawlerView.vue +++ b/schoolNewsWeb/src/views/admin/manage/crontab/NewsCrawlerView.vue @@ -321,8 +321,9 @@ const loadCrawlerList = async () => { const result = await crontabApi.getTaskPage(filter, pageParam); if (result.success && result.dataList) { - crawlerList.value = result.dataList; - total.value = result.pageParam?.totalElements || 0; + const pageDomain = result.pageDomain!; + crawlerList.value = pageDomain.dataList!; + total.value = pageDomain.pageParam.totalElements!; } else { ElMessage.error(result.message || '加载爬虫列表失败'); crawlerList.value = []; diff --git a/schoolNewsWeb/src/views/user-center/MyAchievementsView.vue b/schoolNewsWeb/src/views/user-center/MyAchievementsView.vue index 5f51e90..7b1640a 100644 --- a/schoolNewsWeb/src/views/user-center/MyAchievementsView.vue +++ b/schoolNewsWeb/src/views/user-center/MyAchievementsView.vue @@ -134,7 +134,7 @@ import { Trophy, Check, InfoFilled, Calendar, Star, Present } from '@element-plu import { achievementApi } from '@/apis/achievement'; import type { AchievementVO } from '@/types'; import { AchievementEnumHelper } from '@/types/enums/achievement-enums'; -import { PUBLIC_IMG_PATH } from '@/config'; +import { getAchievementIconUrl } from '@/utils/iconUtils'; // 响应式数据 const loading = ref(false); @@ -215,16 +215,7 @@ function formatDate(dateStr?: string): string { } // 获取图标完整路径 -function getIconUrl(icon?: string): string { - if (!icon) return ''; - // 如果是http或https开头,直接返回 - if (icon.startsWith('http://') || icon.startsWith('https://')) { - return icon; - } - // 否则拼接默认成就图标路径 - const path = `${PUBLIC_IMG_PATH}/achievement`; - return icon.startsWith('/') ? `${path}${icon}` : `${path}/${icon}`; -} +const getIconUrl = getAchievementIconUrl; // 筛选成就 function filterAchievements() { diff --git a/schoolNewsWeb/src/views/user-center/components/UserCard.vue b/schoolNewsWeb/src/views/user-center/components/UserCard.vue index 54ec407..2e6de59 100644 --- a/schoolNewsWeb/src/views/user-center/components/UserCard.vue +++ b/schoolNewsWeb/src/views/user-center/components/UserCard.vue @@ -54,12 +54,9 @@ import {userProfileApi} from '@/apis/usercenter/profile' import defaultAvatarImg from '@/assets/imgs/default-avatar.png'; import maleIcon from '@/assets/imgs/male.svg'; import femaleIcon from '@/assets/imgs/female.svg'; -import V1Icon from '@/assets/imgs/v1.svg'; -import V2Icon from '@/assets/imgs/v2.svg'; -import V3Icon from '@/assets/imgs/v3.svg'; -import V4Icon from '@/assets/imgs/v4.svg'; import { ElMessage } from 'element-plus'; import { useRouter } from 'vue-router'; +import { getLevelIconUrl } from '@/utils/iconUtils'; const router = useRouter(); const userInfo = ref(); @@ -68,13 +65,8 @@ const userInfo = ref(); const defaultAvatar = defaultAvatarImg; const levelIcon = computed(() => { - switch(userInfo.value?.level){ - case 1: return V1Icon; - case 2: return V2Icon; - case 3: return V3Icon; - case 4: return V4Icon; - } - return V1Icon; + const level = userInfo.value?.level || 1; + return getLevelIconUrl(level); }); function handleEdit() {