diff --git a/src/composables/useUserStorage.ts b/src/composables/useUserStorage.ts new file mode 100644 index 0000000..d9ab4cb --- /dev/null +++ b/src/composables/useUserStorage.ts @@ -0,0 +1,79 @@ +import { useUserStore } from '@/store/user' +import { watch } from 'vue' + +/** + * 基于用户ID的响应式存储 + * 自动根据当前登录用户隔离数据 + * + * @param key - 存储键名 + * @param defaultValue - 默认值 + * @returns 响应式引用 + * + * @example + * const selectedExamId = useUserStorage('selectedExamId', 0); + * // 使用方式和普通 ref 完全一样 + * selectedExamId.value = 123; + */ +export function useUserStorage(key: string, defaultValue: T) { + const userStore = useUserStore() + const valueRef = ref(defaultValue) + + // 生成基于用户ID的存储键 + const getStorageKey = () => { + const userId = userStore.info?.id || 'default' + return `user_${userId}_${key}` + } + + // 从 uni.storage 加载数据 + const loadFromStorage = () => { + const storageKey = getStorageKey() + const stored = uni.getStorageSync(storageKey) + + if (stored) { + try { + valueRef.value = JSON.parse(stored) + } + catch { + // 如果是数字类型,直接转换 + if (typeof defaultValue === 'number') { + valueRef.value = Number(stored) as T + } + else { + valueRef.value = stored as T + } + } + } + else { + valueRef.value = defaultValue + } + } + + // 保存到 uni.storage + const saveToStorage = (value: T) => { + const storageKey = getStorageKey() + if (value === undefined || value === null || value === 0 || value === '') { + uni.removeStorageSync(storageKey) + } + else { + const toStore = typeof value === 'object' ? JSON.stringify(value) : String(value) + uni.setStorageSync(storageKey, toStore) + } + } + + // 监听值变化,自动保存 + watch(valueRef, (newValue) => { + saveToStorage(newValue) + }) + + // 监听用户变化,自动重新加载 + watch( + () => userStore.info?.id, + () => { + loadFromStorage() + }, + { immediate: true }, + ) + + return valueRef +} + diff --git a/src/pages/index/score.vue b/src/pages/index/score.vue index c1bd466..60f7605 100644 --- a/src/pages/index/score.vue +++ b/src/pages/index/score.vue @@ -10,6 +10,7 @@ diff --git a/src/store/home.ts b/src/store/home.ts index 47590a7..73f4b23 100644 --- a/src/store/home.ts +++ b/src/store/home.ts @@ -3,6 +3,7 @@ import { whenever } from '@vueuse/core' import { defineStore } from 'pinia' import { computed, ref } from 'vue' import { teacherScoreAnalysisApi } from '@/api' +import { useUserStorage } from '@/composables/useUserStorage' export interface SelectOption { label: string @@ -30,11 +31,11 @@ export const useHomeStore = defineStore( const classList = ref([]) const classGradeMap = ref>(new Map()) - // 已选择的数据 - const selectedClassId = ref(null) - const selectedExamId = ref(null) - const selectedSubjectId = ref(null) - const selectedExamSubjectId = ref(null) + // 已选择的数据(使用 useUserStorage 实现基于用户的持久化) + const selectedClassId = useUserStorage('home_selectedClassId', 0) + const selectedExamId = useUserStorage('home_selectedExamId', 0) + const selectedSubjectId = useUserStorage('home_selectedSubjectId', 0) + const selectedExamSubjectId = useUserStorage('home_selectedExamSubjectId', 0) const selectedGradeKey = computed(() => classGradeMap.value.get(selectedClassId.value || 0) || null) // 计算属性:考试选项