From c7e0c6402ac6b082471575c048c19ea7dcb1d732 Mon Sep 17 00:00:00 2001 From: hb Date: Sat, 2 Aug 2025 11:15:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9D=83=E9=99=90=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/base/server.ts | 20 + src/pages.json | 14 +- src/pages/base/service/index.vue | 210 ++++-- src/pages/system/launchPage/launchPage.vue | 123 +-- .../hr/teacherProfile/RecordMaterials.vue | 2 +- .../routine/JiFenPingJia/JiFenPingJia.vue | 234 +++++- .../routine/JiFenPingJia/PersonalHonor.vue | 370 +++++++++ .../JiFenPingJia/PublicClassAwards.vue | 284 +++++++ .../view/routine/JiFenPingJia/detail.vue | 247 ++++-- .../routine/JiaoXueZiYuan/add-resource.vue | 700 ++++++++++++++++++ .../view/routine/JiaoXueZiYuan/index.vue | 14 +- .../view/routine/JiaoXueZiYuan/indexList.vue | 567 +------------- src/store/modules/user.ts | 73 +- src/utils/permission.ts | 361 ++++++++- 14 files changed, 2474 insertions(+), 745 deletions(-) create mode 100644 src/pages/view/routine/JiFenPingJia/PersonalHonor.vue create mode 100644 src/pages/view/routine/JiFenPingJia/PublicClassAwards.vue create mode 100644 src/pages/view/routine/JiaoXueZiYuan/add-resource.vue diff --git a/src/api/base/server.ts b/src/api/base/server.ts index fce1050..b1d92e2 100644 --- a/src/api/base/server.ts +++ b/src/api/base/server.ts @@ -209,6 +209,16 @@ export const resourcesFindPageApi = async (params: any) => { return await get("/api/resources/findPage", params); }; +// 教师积分查询 +export const jsFindPageJfApi = async (params: any) => { + return await get("/api/js/findPageJf", params); +}; + +// 检查项查询 +export const inspectItemFindAllApi = async (params: any) => { + return await get("/api/inspectItem/findAlls", params); +}; + export const resourcesSaveApi = async (params: any) => { return await post("/api/resources/save", params); }; @@ -339,3 +349,13 @@ export const findAllNj = async () => { export const zwFindAllApi = async () => { return await get("/api/zw/findAll"); }; + +// 获取积分详情数据 +export const getByUserIdAndInspectItemIdApi = async (params: any) => { + return await get("/api/evaluation/getByUserIdAndInspectItemId", params); +}; + +// 清空用户open_id +export const clearUserOpenIdApi = async (params: { userId: string }) => { + return await post(`/api/user/clearOpenId?userId=${params.userId}`); +}; diff --git a/src/pages.json b/src/pages.json index 1336f12..13e0a0c 100644 --- a/src/pages.json +++ b/src/pages.json @@ -389,14 +389,14 @@ } }, { - "path": "pages/view/hr/teacherProfile/PersonalHonor", + "path": "pages/view/routine/JiFenPingJia/PersonalHonor", "style": { "navigationBarTitleText": "个人荣誉", "enablePullDownRefresh": false } }, { - "path": "pages/view/hr/teacherProfile/PublicClassAwards", + "path": "pages/view/routine/JiFenPingJia/PublicClassAwards", "style": { "navigationBarTitleText": "公开课获奖", "enablePullDownRefresh": false @@ -555,6 +555,16 @@ "navigationBarTitleText": "确认签到", "navigationStyle": "custom" } + }, + { + "path": "pages/view/routine/JiaoXueZiYuan/add-resource", + "style": { + "navigationBarTitleText": "上传资源", + "enablePullDownRefresh": false, + "navigationBarBackgroundColor": "#ffffff", + "navigationBarTextStyle": "black", + "backgroundColor": "#f4f5f7" + } } ], "globalStyle": { diff --git a/src/pages/base/service/index.vue b/src/pages/base/service/index.vue index ba4ca29..0b1f6aa 100644 --- a/src/pages/base/service/index.vue +++ b/src/pages/base/service/index.vue @@ -53,6 +53,7 @@ class="section-block" v-for="(section, index) in sections" :key="section.id" + v-show="hasSectionPermission(section)" > diff --git a/src/pages/view/routine/JiFenPingJia/PublicClassAwards.vue b/src/pages/view/routine/JiFenPingJia/PublicClassAwards.vue new file mode 100644 index 0000000..2e59764 --- /dev/null +++ b/src/pages/view/routine/JiFenPingJia/PublicClassAwards.vue @@ -0,0 +1,284 @@ + + + + diff --git a/src/pages/view/routine/JiFenPingJia/detail.vue b/src/pages/view/routine/JiFenPingJia/detail.vue index 34ae60e..575cf00 100644 --- a/src/pages/view/routine/JiFenPingJia/detail.vue +++ b/src/pages/view/routine/JiFenPingJia/detail.vue @@ -46,14 +46,14 @@ - + 证明材料 {{ file.name }} @@ -61,7 +61,7 @@ - + @@ -71,6 +71,18 @@ @@ -225,11 +368,17 @@ onMounted(() => { border-radius: 8rpx; margin-bottom: 10rpx; cursor: pointer; + transition: all 0.3s ease; &:hover { background-color: #e6f7ff; } + &:active { + transform: translateY(1px); + background-color: #d4f1ff; + } + uni-icons { margin-right: 10rpx; } @@ -259,7 +408,7 @@ onMounted(() => { .mobile-btn { width: 100%; height: 88rpx; - background-color: #ff4757; + background-color: #409eff; color: #ffffff; font-size: 32rpx; font-weight: bold; @@ -270,7 +419,7 @@ onMounted(() => { justify-content: center; &:active { - background-color: #ff3742; + background-color: #337ecc; } } } diff --git a/src/pages/view/routine/JiaoXueZiYuan/add-resource.vue b/src/pages/view/routine/JiaoXueZiYuan/add-resource.vue new file mode 100644 index 0000000..0da8039 --- /dev/null +++ b/src/pages/view/routine/JiaoXueZiYuan/add-resource.vue @@ -0,0 +1,700 @@ + + + + + \ No newline at end of file diff --git a/src/pages/view/routine/JiaoXueZiYuan/index.vue b/src/pages/view/routine/JiaoXueZiYuan/index.vue index 49d5a3c..300f44b 100644 --- a/src/pages/view/routine/JiaoXueZiYuan/index.vue +++ b/src/pages/view/routine/JiaoXueZiYuan/index.vue @@ -97,10 +97,20 @@ const selectCategory = (type: any) => { } const goTo = function () { - setData({ - resourceType: curCe.value.key, + const params = { + resourType: curCe.value.key, // 修改参数名为resourType,与后端一致 category: curCategory.value.key, + }; + + console.log('选择的参数:', { + 科目: curType.value?.title, + 年级: curNj.value?.title, + 上下册: curCe.value?.title, + 资源类型: curCategory.value?.label, + 传递参数: params }); + + setData(params); uni.navigateTo({ url: `/pages/view/routine/JiaoXueZiYuan/indexList` }); diff --git a/src/pages/view/routine/JiaoXueZiYuan/indexList.vue b/src/pages/view/routine/JiaoXueZiYuan/indexList.vue index cb6d996..aacee84 100644 --- a/src/pages/view/routine/JiaoXueZiYuan/indexList.vue +++ b/src/pages/view/routine/JiaoXueZiYuan/indexList.vue @@ -88,146 +88,22 @@ - - - - - - {{ modalTitle }} - - - - - - - - - 资源目录 * - - - - {{ getResourceTypeText() || '请选择资源目录' }} - - - - - - - - - - - 课题名称 * - - - - - - - - 课时 * - - - - - - - - 资源类别 * - - - - {{ getCategoryText() || '请选择资源类别' }} - - - - - - - - - - - 资源描述 - - - - - - - - 上传资源 * - - - - 点击或拖拽文件到此区域上传 - 支持 .doc、.docx、.pdf、.ppt、.pptx 等格式 - - - - {{ formData.fileName }} - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index fae8ec4..0d9bf9a 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -3,12 +3,14 @@ import {authenticationApi, loginCode, loginPass, weChatLogin} from "@/api/system import {AUTH_KEY} from "@/config"; import { useDicStore } from "@/store/modules/dic"; import { useCommonStore } from "@/store/modules/common"; +import { refreshPermissionCache, clearPermissionCachePublic } from "@/utils/permission"; interface UserState { userdata: any; jsData: any; token: string; - auth: string[] + auth: string[]; + changeTime: string; // 添加权限变更时间 } export const useUserStore = defineStore({ @@ -22,6 +24,8 @@ export const useUserStore = defineStore({ token: '', //用户注册信息 auth: [], + //权限变更时间 + changeTime: '', }), getters: { getToken(): string { @@ -35,6 +39,9 @@ export const useUserStore = defineStore({ }, getAuth(): string[] { return this.auth; + }, + getChangeTime(): string { + return this.changeTime; } }, actions: { @@ -47,8 +54,33 @@ export const useUserStore = defineStore({ setJs(data: any) { this.jsData = data; }, - setAuth(data: string[]) { + setChangeTime(changeTime: string) { + this.changeTime = changeTime; + }, + setAuth(data: string[], autoRefreshCache: boolean = true) { + console.log('=== setAuth 开始 ==='); + console.log('传入的权限数据:', data); + console.log('权限数量:', data ? data.length : 0); + + // 检查是否与当前权限相同 + if (this.auth && data) { + const isSame = JSON.stringify(this.auth.sort()) === JSON.stringify(data.sort()); + if (isSame) { + console.log('权限数据未变化,跳过更新'); + return; + } + } + + console.log('设置新的权限数据'); this.auth = data; + + // 权限数据更新时,自动刷新缓存(可选) + if (autoRefreshCache && data && data.length > 0) { + console.log('自动刷新权限缓存...'); + refreshPermissionCache(data); + } + + console.log('=== setAuth 完成 ==='); }, /** * @description: 验证码登录 @@ -58,7 +90,7 @@ export const useUserStore = defineStore({ const {result} = await loginCode({phone: params.phone, code: params.code}); this.afterLoginAction(result) } catch (e) { - console.log(e) + // 静默处理错误 } }, /** @@ -69,7 +101,7 @@ export const useUserStore = defineStore({ const {result} = await loginPass({username: params.name, password: params.password}); this.afterLoginAction(result) } catch (e) { - + // 静默处理错误 } }, /** @@ -80,28 +112,49 @@ export const useUserStore = defineStore({ const {result} = await weChatLogin({code: params.code}) this.afterLoginAction(result) } catch (e) { - console.log(e) + // 静默处理错误 } }, /** * @description: 登录成功后的操作 */ afterLoginAction(value: any) { + console.log('=== afterLoginAction 开始 ==='); + console.log('用户数据:', value); + this.setUser(value) this.setJs(value.js); if (value[AUTH_KEY]) { this.setToken(value[AUTH_KEY]) } - authenticationApi({userId: value.id}).then(({result}) => { - if (result) { - this.setAuth(result) - } - }) + + // 检查用户数据中是否已经包含权限信息 + if (value.auth && Array.isArray(value.auth) && value.auth.length > 0) { + console.log('✅ 用户数据中包含权限信息:', value.auth); + console.log('权限数量:', value.auth.length); + this.setAuth(value.auth, false); + } else { + console.log('用户数据中无权限信息,调用 authenticationApi 获取权限...'); + authenticationApi({userId: value.id}).then(({result}) => { + if (result) { + console.log('✅ 获取到权限数据:', result); + console.log('权限数量:', result.length); + this.setAuth(result, false); + } else { + console.log('❌ authenticationApi 返回空结果'); + } + }).catch(error => { + console.error('❌ authenticationApi 调用失败:', error); + }) + } }, /** * @description: 注销 */ logout() { + // 清除权限缓存 + clearPermissionCachePublic(); + this.setToken('') this.setUser({}) this.setJs({}) diff --git a/src/utils/permission.ts b/src/utils/permission.ts index 9d61774..2e5d358 100644 --- a/src/utils/permission.ts +++ b/src/utils/permission.ts @@ -2,28 +2,101 @@ import {ISROUTERINTERCEPT} from "@/config"; import {getRouter} from "@/utils/uniapp"; import {useUserStore} from "@/store/modules/user"; -export function _auth(autd: string) { - const {getAuth} = useUserStore() - return getAuth.includes(autd); +// 权限缓存相关常量 +const PERMISSION_CACHE_KEY = 'user_permissions_cache'; + +// 权限缓存接口 +interface PermissionCache { + permissions: string[]; + timestamp: number; + userId: string; + changeTime: string; } -function loginPage(url: string) { - uni.redirectTo({ - url: "/pages/system/login/login?redirect=" + url, - }); +// 存储工具函数 +function setStorage(key: string, value: any): void { + try { + if (typeof localStorage !== 'undefined') { + const jsonValue = JSON.stringify(value); + localStorage.setItem(key, jsonValue); + } else { + uni.setStorageSync(key, value); + } + } catch (error) { + // 静默处理错误 + } } +function getStorage(key: string): any { + try { + if (typeof localStorage !== 'undefined') { + const value = localStorage.getItem(key); + return value ? JSON.parse(value) : null; + } else { + const value = uni.getStorageSync(key); + return value; + } + } catch (error) { + return null; + } +} + +// 从app-user中获取权限变更时间 +function getChangeTimeFromAppUser(): string | null { + try { + const userStore = useUserStore(); + if (userStore.getChangeTime && userStore.getChangeTime.trim() !== '') { + return userStore.getChangeTime; + } + + if (typeof localStorage !== 'undefined') { + const appUser = localStorage.getItem('app-user'); + if (appUser) { + const userData = JSON.parse(appUser); + if (userData.changeTime) { + return userData.changeTime; + } + } + } + + return null; + } catch (error) { + return null; + } +} + +// 将权限变更时间存储到app-user中 +function setChangeTimeToAppUser(changeTime: string): void { + try { + const userStore = useUserStore(); + userStore.setChangeTime(changeTime); + + if (typeof localStorage !== 'undefined') { + const appUser = localStorage.getItem('app-user'); + if (appUser) { + const userData = JSON.parse(appUser); + userData.changeTime = changeTime; + localStorage.setItem('app-user', JSON.stringify(userData)); + } + } + } catch (error) { + // 静默处理错误 + } +} + +// 路由拦截器 - 默认导出 export default function (whitelist: WhiteList) { const WHITELIST = ['/', ...whitelist, {pattern: /^\/pages\/system\/.*/}]; const list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; - // 用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器 + list.forEach((item) => { uni.addInterceptor(item, { invoke(e) { // 获取要跳转的页面路径(url去掉"?"和"?"后的参数) const url = e.url.split("?")[0]; + // 判断当前窗口是白名单,如果是则不重定向路由 - let pass; + let pass = false; if (WHITELIST) { pass = WHITELIST.some((item) => { if (typeof item === "object" && item.pattern) { @@ -32,6 +105,7 @@ export default function (whitelist: WhiteList) { return url === item; }); } + // 不是白名单并且没有token const store = useUserStore(); if (!pass && !store.getToken) { @@ -41,15 +115,206 @@ export default function (whitelist: WhiteList) { return e; }, fail(err) { - // 失败回调拦截 - console.log(err); + // 静默处理错误 } }); }); } -//判断是否登录 -export function getLogin(): boolean { +/** + * 获取权限缓存 + */ +function getPermissionCache(): PermissionCache | null { + try { + const cacheData = getStorage(PERMISSION_CACHE_KEY); + const changeTime = getChangeTimeFromAppUser(); + + if (!cacheData || !changeTime) { + return null; + } + + return { + permissions: cacheData.permissions, + timestamp: cacheData.timestamp, + userId: cacheData.userId, + changeTime: cacheData.changeTime + }; + } catch (error) { + return null; + } +} + +/** + * 设置权限缓存 + * @param permissions 权限列表 + * @param userId 用户ID + * @param changeTime 权限变更时间(可选) + */ +function setPermissionCache(permissions: string[], userId: string, changeTime?: string): void { + try { + const defaultChangeTime = '2024-01-01 00:00:00'; + const finalChangeTime = changeTime || defaultChangeTime; + + const cacheData: PermissionCache = { + permissions, + timestamp: Date.now(), + userId, + changeTime: finalChangeTime + }; + + setStorage(PERMISSION_CACHE_KEY, cacheData); + setChangeTimeToAppUser(finalChangeTime); + } catch (error) { + // 静默处理错误 + } +} + +/** + * 清除权限缓存 + */ +function clearPermissionCache(): void { + try { + if (typeof localStorage !== 'undefined') { + localStorage.removeItem(PERMISSION_CACHE_KEY); + } else { + uni.removeStorageSync(PERMISSION_CACHE_KEY); + } + } catch (error) { + // 静默处理错误 + } +} + +/** + * 验证缓存是否有效 + */ +function isCacheValid(cache: PermissionCache, currentUserId: string): boolean { + return cache.userId === currentUserId; +} + +/** + * 获取用户权限列表(带缓存) + * @param currentChangeTime 当前服务器返回的权限变更时间 + * @returns 权限列表 + */ +function getUserPermissionsWithCache(currentChangeTime?: string): string[] { + const userStore = useUserStore(); + const currentUser = userStore.getUser; + const currentUserId = currentUser?.id || currentUser?.userdata?.id; + + if (!currentUserId) { + return userStore.getAuth; + } + + const cache = getPermissionCache(); + if (cache && isCacheValid(cache, currentUserId)) { + if (currentChangeTime) { + const serverTime = new Date(currentChangeTime).getTime(); + const cacheTime = new Date(cache.changeTime).getTime(); + + if (serverTime > cacheTime) { + const permissions = userStore.getAuth; + if (permissions && permissions.length > 0) { + setPermissionCache(permissions, currentUserId, currentChangeTime); + } + return permissions; + } else { + return cache.permissions; + } + } else { + return cache.permissions; + } + } + + const permissions = userStore.getAuth; + if (permissions && permissions.length > 0) { + setPermissionCache(permissions, currentUserId, currentChangeTime); + } + + return permissions; +} + +/** + * 刷新权限缓存 + * @param permissions 新的权限列表 + * @param changeTime 权限变更时间(可选) + */ +export function refreshPermissionCache(permissions?: string[], changeTime?: string): void { + const userStore = useUserStore(); + const currentUser = userStore.getUser; + const currentUserId = currentUser?.id || currentUser?.userdata?.id; + + if (!currentUserId) { + return; + } + + const permissionList = permissions || userStore.getAuth; + + const currentCache = getPermissionCache(); + if (currentCache && currentCache.permissions && permissionList) { + const isSame = JSON.stringify(currentCache.permissions.sort()) === JSON.stringify(permissionList.sort()); + if (isSame && currentCache.changeTime === changeTime) { + return; + } + } + + setPermissionCache(permissionList, currentUserId, changeTime); + + if (changeTime) { + userStore.setChangeTime(changeTime); + } +} + +/** + * 清除权限缓存(供外部调用) + */ +export function clearPermissionCachePublic(): void { + clearPermissionCache(); +} + +// 权限检查函数 +export function _auth(autd: string, changeTime?: string) { + const permissions = getUserPermissionsWithCache(changeTime); + return permissions.includes(autd); +} + +export function hasPermission(permissionKey: string, changeTime?: string): boolean { + if (!permissionKey) return true; + const permissions = getUserPermissionsWithCache(changeTime); + // 去重处理,避免重复权限影响判断 + const uniquePermissions = [...new Set(permissions)]; + return uniquePermissions.includes(permissionKey); +} + +export function hasAnyPermission(permissionKeys: string[], changeTime?: string): boolean { + if (!permissionKeys || permissionKeys.length === 0) return true; + const permissions = getUserPermissionsWithCache(changeTime); + // 去重处理,避免重复权限影响判断 + const uniquePermissions = [...new Set(permissions)]; + return permissionKeys.some(key => uniquePermissions.includes(key)); +} + +export function hasAllPermissions(permissionKeys: string[], changeTime?: string): boolean { + if (!permissionKeys || permissionKeys.length === 0) return true; + const permissions = getUserPermissionsWithCache(changeTime); + // 去重处理,避免重复权限影响判断 + const uniquePermissions = [...new Set(permissions)]; + return permissionKeys.every(key => uniquePermissions.includes(key)); +} + +export function getUserPermissions(changeTime?: string): string[] { + const permissions = getUserPermissionsWithCache(changeTime); + // 返回去重后的权限列表 + return permissions ? [...new Set(permissions)] : []; +} + +export function getLogin(): void { + clearPermissionCache(); + uni.reLaunch({ + url: "/pages/system/login/login", + }); +} + +export function isLogin(): boolean { if (ISROUTERINTERCEPT) { const store = useUserStore(); if (!store.getToken) { @@ -65,4 +330,72 @@ export function getLogin(): boolean { return true } return false -} \ No newline at end of file +} + +function loginPage(url: string) { + uni.redirectTo({ + url: "/pages/system/login/login?redirect=" + url, + }); +} + +export const ROUTINE_PERMISSIONS = { + JIAO_XUE_ZI_YUAN: 'JiaoXueZiYuan', + JI_FEN_PING_JIA: 'JiFenPingJia', + GONG_ZUO_LIANG: 'GongZuoLiang', + RENG_JIAO_RENG_ZHI: 'RengJiaoRengZhi', + SHI_TANG_XUN_CHA: 'ShiTangXunCha', + KE_FU_XUN_CHA: 'kefuxuncha', + GROUP_TEACHING: 'groupTeaching', + NOTICE: 'notice', + ROUTINE: 'routine', +} as const; + +export function isTeacherUser(): boolean { + const userStore = useUserStore(); + const user = userStore.getUser; + return user && user.userType === 'teacher'; +} + +export function isAdminUser(): boolean { + const userStore = useUserStore(); + const user = userStore.getUser; + return user && user.userType === 'admin'; +} + +export const PermissionCacheManager = { + getCacheInfo() { + const cache = getPermissionCache(); + const changeTime = getChangeTimeFromAppUser(); + + return { + hasCache: !!cache, + changeTime: changeTime ? new Date(changeTime).toLocaleString() : null, + isExpired: cache ? Date.now() > cache.timestamp : true, + cacheSize: cache ? cache.permissions.length : 0 + }; + }, + + /** + * 显示详细的缓存信息(调试用) + */ + debugCache() { + // 移除所有调试信息 + }, + + forceRefresh() { + const userStore = useUserStore(); + const permissions = userStore.getAuth; + const currentUser = userStore.getUser; + const currentUserId = currentUser?.id || currentUser?.userdata?.id; + + if (currentUserId && permissions) { + setPermissionCache(permissions, currentUserId); + return true; + } + return false; + }, + + clear() { + clearPermissionCache(); + } +}; \ No newline at end of file