SAAS模式调整

This commit is contained in:
hebo 2026-02-23 17:31:01 +08:00
parent 0562efd6e8
commit 73515ab6a5
11 changed files with 279 additions and 310 deletions

View File

@ -3,6 +3,9 @@ import {onHide, onLaunch, onShow} from "@dcloudio/uni-app";
onLaunch(() => {
console.log("App Launch");
// #ifdef H5
document.title = "数字校园";
// #endif
});
onShow(() => {
console.log("App Show");

View File

@ -119,13 +119,6 @@ export const jzXsQjActivitiHistoryApi = async (params: any) => {
return await get("/activiti/history/historicFlow", params);
};
/**
*
*/
export const getUserLatestInfoApi = async () => {
return await get("/open/login/getLatestInfo");
};
/**
* ID查询作品执行数据
*/

View File

@ -0,0 +1,16 @@
import { get } from "@/utils/request";
/** 短时缓存,避免 launchPage 连续跳转时重复调用 */
let _changeTimeCache: { promise: Promise<any>; ts: number } | null = null;
const CACHE_MS = 10000; // 10 秒内复用
/** 获取权限变更时间戳,用于判断本地缓存的菜单是否需重新拉取 */
export const getPermissionChangeTimeApi = () => {
const now = Date.now();
if (_changeTimeCache && now - _changeTimeCache.ts < CACHE_MS) {
return _changeTimeCache.promise;
}
const promise = get("/api/comConfig/getPermissionChangeTime");
_changeTimeCache = { promise, ts: now };
return promise;
};

View File

@ -44,11 +44,6 @@ export const weChatLogin = async (param: any) => {
return await get("/userlogin/weloginByCode", param);
};
//获取用户按钮权限
export const authenticationApi = async (param: { userId: string }) => {
return await get("/api/authentication/find-by-user", param);
};
//获取公众号票据
export const wxConfigApi = async (param: any) => {
return await post("/userlogin/wxConfig", param);

17
src/api/system/menu.ts Normal file
View File

@ -0,0 +1,17 @@
import { get } from "@/utils/request";
/** 手机端菜单树节点 */
export interface MobileMenuTreeNode {
id: number;
parentId: number | null;
screenName: string;
normalCss?: string;
pagePath?: string;
sortNum: number;
authCode?: string;
children: MobileMenuTreeNode[];
}
/** 获取手机端菜单(家长端) */
export const getMobileMenuApi = () =>
get<{ result: MobileMenuTreeNode[] }>("/api/screen/find-mobile-menu");

View File

@ -24,7 +24,7 @@
<view class="title-line"></view>
</view>
<view class="grid-menu">
<view v-for="(item, index) in menuItems" :key="index" v-show="hasPermissionDirect(item.permissionKey)"
<view v-for="(item, index) in menuItems" :key="item.id ?? index"
class="grid-item" @click="handleMenuClick(item)">
<view class="grid-icon-container">
<view class="icon-background"></view>
@ -66,195 +66,76 @@
</template>
<script setup lang="ts">
import { ref, computed, onMounted, watch } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { ref, computed, onMounted, watch, reactive } from "vue";
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
import { cmsArticlePageApi, getUserLatestInfoApi } from "@/api/base/server";
import { getNoticeListApi } from "@/api/base/notice";
import { getMobileMenuApi } from "@/api/system/menu";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import { hasPermission } from "@/utils/permission";
import { useMenuStore } from "@/store/modules/menu";
import { type MobileMenuTreeNode } from "@/api/system/menu";
import { PageUtils } from "@/utils/pageUtil";
import { useDebounce } from "@/utils/debounce";
const { getCurXs } = useUserStore();
const { setData, getAppCode, setGlobal } = useDataStore();
const userStore = useUserStore();
const { getCurXs } = userStore;
const dataStore = useDataStore();
const menuStore = useMenuStore();
const { setData, getAppCode, setGlobal } = dataStore;
const { debounce } = useDebounce(2000);
//
const { getLastRefreshTime, getRefreshInterval, setLastRefreshTime, updateStudentInfo, updateStudentList } = useUserStore();
const REFRESH_INTERVAL = 7 * 24 * 60 * 60 * 1000; // 17
/** 家长端菜单项(后端 getMobileMenuApi 动态加载) */
interface HomeMenuItem {
id?: number | string;
title: string;
icon: string;
path?: string;
permissionKey?: string;
action?: string;
lxId?: string;
}
// changeTime
const getCurrentChangeTime = () => {
try {
const userDataStr = uni.getStorageSync('app-user');
if (!userDataStr) return null;
const userData = typeof userDataStr === 'string' ? JSON.parse(userDataStr) : userDataStr;
return userData?.changeTime || null;
} catch (error) {
console.error('获取changeTime失败:', error);
return null;
}
/** 家长端特殊菜单:选课/退费/缴费需 lxId + action后端 auth_code 映射 */
const JZD_SPECIAL_MENU: Record<string, { lxId: string; action: string }> = {
"school-xqkxk": { lxId: "962488654", action: "jf" }, //
"school-jlbxk": { lxId: "816059832", action: "jf" }, //
"school-jcjf": { lxId: "JC", action: "jf" }, //
"school-xqk-tf": { lxId: "962488654", action: "tf" }, // 退
"school-jlb-tf": { lxId: "816059832", action: "tf" }, // 退
};
// changeTime
const checkPermission = (permissionKey: string) => {
const changeTime = getCurrentChangeTime();
return hasPermission(permissionKey, changeTime);
};
//
const hasPermissionDirect = (permissionKey: string) => {
if (!permissionKey) return true;
const userStore = useUserStore();
const permissions = userStore.getAuth;
if (!permissions || permissions.length === 0) return false;
const uniquePermissions = [...new Set(permissions)];
return uniquePermissions.includes(permissionKey);
};
//
const checkAndRefreshStudentInfo = async () => {
const lastRefreshTime = getLastRefreshTime;
const currentTime = Date.now();
if (!lastRefreshTime || (currentTime - lastRefreshTime) > REFRESH_INTERVAL) {
await refreshStudentInfo();
setLastRefreshTime(currentTime);
}
};
//
const refreshStudentInfo = async () => {
try {
const response = await getUserLatestInfoApi();
if (response && response.result) {
//
if (response.result.xsList && response.result.xsList.length > 0) {
updateStudentList(response.result.xsList);
//
const currentXsId = curXs.value?.id;
if (currentXsId) {
const currentStudent = response.result.xsList.find((xs: any) => xs.id === currentXsId);
if (currentStudent) {
updateStudentInfo(currentStudent);
} else {
//
updateStudentInfo(response.result.xsList[0]);
}
} else {
//
updateStudentInfo(response.result.xsList[0]);
}
//
function flattenMenuToItems(nodes: MobileMenuTreeNode[]): HomeMenuItem[] {
const items: HomeMenuItem[] = [];
const walk = (list: MobileMenuTreeNode[]) => {
for (const node of list || []) {
if (node.pagePath) {
const icon = (node.normalCss && /^[a-zA-Z0-9_-]+$/.test(node.normalCss))
? `/static/base/home/${node.normalCss}.png`
: "/static/base/home/file-text-line.png";
const authCode = node.authCode || "";
const special = authCode ? JZD_SPECIAL_MENU[authCode] : undefined;
items.push({
id: node.id,
title: node.screenName,
icon,
path: node.pagePath,
permissionKey: authCode,
...(special && { lxId: special.lxId, action: special.action }),
});
}
if (node.children?.length) walk(node.children);
}
} catch (error) {
//
};
if (nodes.length === 1 && !nodes[0].pagePath && (nodes[0].children?.length ?? 0) > 0) {
walk(nodes[0].children!);
} else {
walk(nodes);
}
};
return items;
}
//
const menuItems = ref([
{
title: "班级课表",
icon: "/static/base/home/book-read-line.png",
path: "/pages/base/class-schedule/index",
permissionKey: "school-bjkb", //
},
{
title: "学业监测",
icon: "/static/base/home/file-search-line.png",
path: "/pages/base/grades/list",
permissionKey: "school-cjcx", //
},
{
title: "在线请假",
icon: "/static/base/home/draft-line.png",
path: "/pages/base/qj/index",
permissionKey: "school-zxqj", // 线
},
// TODO:
// {
// title: "",
// icon: "/static/base/home/file-transfer-line.png",
// path: "/pages/base/campus-access/index",
// permissionKey: "school-jcxy", //
// },
{
title: "家校沟通",
icon: "/static/base/home/file-transfer-line.png",
path: "/pages/base/jl/index",
permissionKey: "school-jxgt", //
},
{
title: "兴趣课",
icon: "/static/base/home/file-text-line.png",
path: "/pages/base/xk/xqk",
permissionKey: "school-xqk", //
},
{
title: "俱乐部",
icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/xk/jlb",
permissionKey: "school-jlb", //
},
{
title: "就餐详情",
icon: "/static/base/home/jcxq.png",
path: "/pages/base/jc/index",
permissionKey: "school-jcxq",
},
{
title: "兴趣课选课",
icon: "/static/base/home/file-text-line.png",
path: "/pages/base/gzs/index",
permissionKey: "school-xqkxk", //
action: 'jf',
lxId: '962488654',
},
{
title: "俱乐部选课",
icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/gzs/index",
permissionKey: "school-jlbxk", //
action: 'jf',
lxId: '816059832',
},
{
title: "就餐报名",
icon: "/static/base/home/jcxq.png",
path: "/pages/base/gzs/index",
permissionKey: "school-jcjf",
action: 'jf',
lxId: 'JC',
},
{
title: "兴趣课退费",
icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/gzs/tf",
permissionKey: "school-xqk-tf",
action: "tf",
lxId: "962488654",
},
{
title: "俱乐部退费",
icon: "/static/base/home/contacts-book-3-line.png",
path: "/pages/base/gzs/tf",
permissionKey: "school-jlb-tf",
action: "tf",
lxId: "816059832",
},
{
title: "新苗成长",
icon: "/static/base/home/xszp.png",
path: "/pages/base/xszp/index",
permissionKey: "school-xszp",
},
]);
const menuItems = ref<HomeMenuItem[]>([]);
//
const announcements = ref<any>([])
@ -333,11 +214,26 @@ const getArticleList = async () => {
onMounted(async () => {
setGlobal({ from: 'home' });
// launchPage menuStore
const cachedMenu = menuStore.getMobileMenu;
if (cachedMenu?.length > 0) {
menuItems.value = flattenMenuToItems(cachedMenu);
} else if (userStore.getToken) {
// launchPage token
try {
const r = await getMobileMenuApi();
if (r?.result && Array.isArray(r.result) && r.result.length > 0) {
menuStore.setMobileMenu(r.result);
menuItems.value = flattenMenuToItems(r.result);
}
} catch (_e) {}
}
//
if (curXs.value && curXs.value.njmcId) {
getArticleList();
} else {
// store
setTimeout(() => {
if (curXs.value && curXs.value.njmcId) {
getArticleList();
@ -345,39 +241,11 @@ onMounted(async () => {
}, 100);
}
//
await checkAndRefreshStudentInfo();
//
const userStore = useUserStore();
const changeTime = userStore.getChangeTime;
if (changeTime) {
// changeTime
const { PermissionCacheManager } = await import('@/utils/permission');
const cacheInfo = PermissionCacheManager.getCacheInfo();
if (cacheInfo.hasCache && cacheInfo.changeTime) {
const serverTime = new Date(changeTime).getTime();
const cacheTime = new Date(cacheInfo.changeTime).getTime();
if (serverTime > cacheTime) {
//
const { refreshPermissionCache } = await import('@/utils/permission');
const currentPermissions = userStore.getAuth;
if (currentPermissions && currentPermissions.length > 0) {
refreshPermissionCache(currentPermissions, changeTime);
}
}
}
}
//
await checkSubscribeStatus();
});
//
const checkSubscribeStatus = async () => {
const userStore = useUserStore();
const userInfo = userStore.getUser;
if (userInfo && !userInfo.subscribed) {
@ -407,11 +275,6 @@ const showSubscribeReminder = () => {
});
};
//
onShow(async () => {
await checkAndRefreshStudentInfo();
});
//
watch(curXs, (newXs, oldXs) => {
if (newXs && newXs.njmcId) {

View File

@ -15,12 +15,16 @@
import { onLoad } from "@dcloudio/uni-app";
import { useDataStore } from "@/store/modules/data";
import { useUserStore } from "@/store/modules/user";
import { useMenuStore } from "@/store/modules/menu";
import { checkOpenId } from "@/api/system/login";
import { refreshPermissionCache } from "@/utils/permission";
import { getMobileMenuApi } from "@/api/system/menu";
import { getPermissionChangeTimeApi } from "@/api/system/config";
import { PageUtils } from "@/utils/pageUtil";
const { setGlobal } = useDataStore();
const dataStore = useDataStore();
const { setGlobal } = dataStore;
const userStore = useUserStore();
const menuStore = useMenuStore();
const isShow = ref(true);
const toLogin = () => {
@ -31,7 +35,7 @@ const toLogin = () => {
//
const initGlobalData = (data: any) => {
let gData = data || {};
let gData = { ...(data || {}) };
let lxId = gData.lxId;
//
if (!lxId && gData.type) {
@ -66,23 +70,82 @@ const initGlobalData = (data: any) => {
onLoad(async (data: any) => {
const gData = initGlobalData(data);
//
if (gData.fromLogin === "1") {
let needFetchMenu = true;
try {
const timeRes = await getPermissionChangeTimeApi();
const serverChangeTime = String((timeRes as any)?.result ?? "");
const localChangeTime = userStore.getChangeTime || "";
const localMenu = menuStore.getMobileMenu || [];
needFetchMenu =
serverChangeTime !== localChangeTime || !localMenu?.length;
console.log("[launchPage] fromLogin", {
timeResRaw: JSON.stringify(timeRes),
serverChangeTime,
localChangeTime,
localMenuLength: localMenu?.length ?? 0,
needFetchMenu,
});
if (serverChangeTime) userStore.setChangeTime(serverChangeTime);
} catch (_e) {
needFetchMenu = true;
console.warn("[launchPage] fromLogin getPermissionChangeTime 异常", _e);
}
if (needFetchMenu) {
try {
const r = await getMobileMenuApi();
if (r?.result && Array.isArray(r.result) && r.result.length > 0) {
menuStore.setMobileMenu(r.result);
}
} catch (_e) {}
}
PageUtils.toHome(gData.lxId, gData.action);
return;
}
if (gData.openId) {
try {
const res = await checkOpenId({ openId: gData.openId, appCode: "JZ" });
if (res.resultCode == 1 && res.result) {
//
// afterLoginAction afterLoginAction logout changeTime menuStore
const savedChangeTime = userStore.getChangeTime || "";
const savedMenu = menuStore.getMobileMenu || [];
userStore.afterLoginAction(res.result);
// changeTime
if (gData.changeTime) {
const currentPermissions = userStore.getAuth;
if (currentPermissions && currentPermissions.length > 0) {
refreshPermissionCache(currentPermissions, data.changeTime);
}
//
let needFetchMenu = true;
try {
const timeRes = await getPermissionChangeTimeApi();
const serverChangeTime = String((timeRes as any)?.result ?? "");
needFetchMenu =
serverChangeTime !== savedChangeTime || !savedMenu?.length;
console.log("[launchPage] openId", {
timeResRaw: JSON.stringify(timeRes),
serverChangeTime,
savedChangeTime,
savedMenuLength: savedMenu?.length ?? 0,
needFetchMenu,
});
if (serverChangeTime) userStore.setChangeTime(serverChangeTime);
} catch (_e) {
needFetchMenu = true;
console.warn("[launchPage] openId getPermissionChangeTime 异常", _e);
}
//
if (needFetchMenu) {
try {
const r = await getMobileMenuApi();
if (r?.result && Array.isArray(r.result) && r.result.length > 0) {
menuStore.setMobileMenu(r.result);
}
} catch (_e) {}
} else {
menuStore.setMobileMenu(savedMenu); // logout
}
PageUtils.toHome(gData.lxId, gData.action);
return;
}

View File

@ -17,33 +17,16 @@
<view class="avatar-section">
<view class="avatar-uploader-container-rect">
<CustomUpload
@select="(event:any) => afterRead(event, index)"
@close="handleAvatarClose(index)"
:sourceType="['camera', 'album']"
:value="imagUrl(student.xstx)"
>
<view class="avatar-placeholder">
<view class="wh-full flex-col-center">
<svg
t="1729656215869"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5302"
width="32"
height="32"
>
<path
d="M851.552 890.88 172.448 890.88c-74.592 0-135.296-60.672-135.296-135.296L37.152 370.752c0-74.624 60.672-135.328 135.296-135.328l132.16 0L302.912 195.904c0-34.624 28.192-62.816 62.816-62.816l302.016 0c29.408 0 53.312 23.904 53.312 53.312l0 49.024 130.464 0c74.592 0 135.296 60.672 135.296 135.328l0 384.832C986.816 830.208 926.144 890.88 851.552 890.88zM172.448 283.456c-48.128 0-87.296 39.168-87.296 87.328l0 384.832c0 48.128 39.168 87.296 87.296 87.296l679.104 0c48.128 0 87.296-39.168 87.296-87.296L938.848 370.752c0-48.16-39.168-87.328-87.296-87.328L716.8 283.424c-24.096 0-43.712-19.616-43.712-43.712L673.088 186.4c0-2.944-2.368-5.312-5.312-5.312l-302.016 0c-8.16 0-14.816 6.656-14.816 14.816L350.944 237.12c0 25.536-20.768 46.304-46.304 46.304L172.448 283.424zM512 755.84c-107.04 0-194.08-87.072-194.08-194.08S404.992 367.68 512 367.68s194.08 87.072 194.08 194.08S619.04 755.84 512 755.84zM512 415.68c-80.576 0-146.08 65.536-146.08 146.08S431.456 707.84 512 707.84s146.08-65.536 146.08-146.08S592.576 415.68 512 415.68zM816.8 438.016c-25.568 0-46.336-20.768-46.336-46.336s20.768-46.336 46.336-46.336 46.336 20.768 46.336 46.336S842.368 438.016 816.8 438.016zM816.8 390.016l-1.664 1.664c0 0.896 0.736 1.664 1.664 1.664L816.8 390.016z"
fill="#cdcdcd"
p-id="5303"
></path>
</svg>
</view>
</view>
</CustomUpload>
<ImageVideoUpload
:image-list="student.xstx ? [{ url: student.xstx }] : []"
@update:image-list="(list: any[]) => onAvatarUpdate(index, list)"
:enable-video="false"
:enable-file="false"
:max-image-count="1"
:upload-api="attachmentUpload"
:show-section-title="false"
:auto-upload="true"
/>
</view>
<text class="avatar-upload-note">上传学生人像用于校园进出</text>
</view>
@ -120,18 +103,15 @@
<script lang="ts" setup>
import { hideLoading, showLoading, showToast } from "@/utils/uniapp";
import { ref } from "vue";
import { nextTick, ref } from "vue";
import { attachmentUpload } from "@/api/system/upload";
import CustomUpload from "/src/components/BasicUpload/CustomUpload.vue";
import { ImageVideoUpload } from "@/components/ImageVideoUpload";
import { useForm } from "@/components/BasicForm/hooks/useForm";
import { loginRegisterJzApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import { useDicStore } from "@/store/modules/dic";
import { imagUrl } from "@/utils";
import { refreshPermissionCache } from "@/utils/permission";
import { PageUtils } from "@/utils/pageUtil";
const dicOptions = ref<any>([[[]]]);
const dicPickerRef = ref();
@ -221,34 +201,8 @@ const dicChanged = (dicArr: any) => {
curXs.value.jzxsgxmc = dic.dictionaryCode;
};
async function afterRead(event: any, index: number) {
if (!event.tempFilePaths || event.tempFilePaths.length === 0) {
showToast({ title: "图片选择失败", icon: "none" });
return;
}
const tempFilePath = event.tempFilePaths[0];
showLoading({ title: "上传中" });
try {
const res = (await attachmentUpload(tempFilePath)) as {
result: Array<{ filePath: string }>;
};
const result = res.result;
if (result && result.length > 0 && result[0].filePath) {
students.value[index].xstx = result[0].filePath;
showToast({ title: "上传成功" });
} else {
showToast({ title: "上传失败,请重试", icon: "none" });
}
} catch (error) {
showToast({ title: "上传出错", icon: "none" });
console.error("Upload error:", error);
} finally {
hideLoading();
}
}
function handleAvatarClose(index: number) {
students.value[index].xstx = "";
function onAvatarUpdate(index: number, list: any[]) {
students.value[index].xstx = list[0]?.url || "";
}
function addMoreChildren() {
@ -301,15 +255,13 @@ async function submit() {
hideLoading();
if (res.resultCode == 1) {
userStore.afterLoginAction(res.result);
// changeTime
if (res.result && res.result.changeTime) {
const currentPermissions = userStore.getAuth;
if (currentPermissions && currentPermissions.length > 0) {
refreshPermissionCache(currentPermissions, res.result.changeTime);
}
}
PageUtils.toHome(getGlobal.lxId, getGlobal.action);
// store launchPage token
await nextTick();
setTimeout(() => {
uni.reLaunch({
url: `/pages/system/launchPage/launchPage?fromLogin=1&lxId=${getGlobal.lxId || ""}&action=${getGlobal.action || ""}`,
});
}, 50);
} else {
showToast({ title: res.message || "提交失败", icon: "none" });
}
@ -363,17 +315,42 @@ onMounted(async () => {
/* Keep avatar uploader styles relevant to CustomUpload */
/* Replace with rectangular styles */
.avatar-uploader-container-rect {
/* Assuming uni.rpx units based on class names like wi-180, he-240 */
width: 180rpx;
height: 240rpx;
margin: 0 auto 10px auto; /* mx-auto mb-10 */
border-radius: 6px; /* r-md approximation */
margin: 0 auto 10px auto;
border-radius: 6px;
border: 1px solid #cccccc;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
background-color: #fafafa;
/* 头像模式:图片自适应填满容器 */
:deep(.image-video-upload) {
width: 100%;
height: 100%;
}
:deep(.upload-section),
:deep(.image-list) {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
:deep(.image-item),
:deep(.add-btn) {
width: 100% !important;
height: 100% !important;
min-width: 100%;
min-height: 100%;
}
:deep(.image-preview) {
width: 100%;
height: 100%;
object-fit: cover; /* 自适应:保持比例填满,多余裁剪 */
}
}
/* Remove old circular styles */

View File

@ -1,5 +1,6 @@
import { get } from "lodash";
import { defineStore } from "pinia";
import type { MobileMenuTreeNode } from "@/api/system/menu";
export const useDataStore = defineStore({
id: "data",
@ -8,6 +9,8 @@ export const useDataStore = defineStore({
kcData: {},
global: {},
file: {},
/** 手机端菜单树(家长端 home 页用) */
mobileMenu: [] as MobileMenuTreeNode[],
params: {},
appCode: "JZ",
qk: {},
@ -54,6 +57,9 @@ export const useDataStore = defineStore({
getXxts(): any {
return this.xxts;
},
getMobileMenu(): MobileMenuTreeNode[] {
return this.mobileMenu || [];
},
},
actions: {
cleanData() {
@ -68,6 +74,7 @@ export const useDataStore = defineStore({
this.jcBz = {};
this.lcgl = {};
this.xxts = {};
this.mobileMenu = [];
this.$reset();
},
setData(data: any) {
@ -103,6 +110,9 @@ export const useDataStore = defineStore({
setXxts(data: any) {
this.xxts = data;
},
setMobileMenu(menu: MobileMenuTreeNode[]) {
this.mobileMenu = menu && Array.isArray(menu) ? menu : [];
},
},
persist: {
enabled: true,

34
src/store/modules/menu.ts Normal file
View File

@ -0,0 +1,34 @@
import { defineStore } from "pinia";
import type { MobileMenuTreeNode } from "@/api/system/menu";
export const useMenuStore = defineStore({
id: "app-Menu",
state: () => ({
/** 树形菜单数据,持久化到 localStorage key: app-Menu */
mobileMenu: [] as MobileMenuTreeNode[],
}),
getters: {
getMobileMenu(): MobileMenuTreeNode[] {
return this.mobileMenu || [];
},
},
actions: {
/** 清空菜单 */
clearMenu() {
this.mobileMenu = [];
},
/**
*
* @param menu
*/
setMobileMenu(menu: MobileMenuTreeNode[]) {
this.clearMenu();
this.mobileMenu = menu && Array.isArray(menu) ? [...menu] : [];
},
},
persist: {
enabled: true,
detached: true,
H5Storage: localStorage,
},
});

View File

@ -1,11 +1,12 @@
import { defineStore } from "pinia";
import { authenticationApi, loginCode, loginPass, weChatLogin, checkOpenId } from "@/api/system/login";
import { loginCode, loginPass, weChatLogin, checkOpenId } from "@/api/system/login";
import { AUTH_KEY } from "@/config";
import { imagUrl } from "@/utils";
import { useWebSocket } from '@/utils/webSocket/webSocket'
import { useDicStore } from "@/store/modules/dic";
import { useCommonStore } from "@/store/modules/common";
import { useDataStore } from "@/store/modules/data";
import { useMenuStore } from "@/store/modules/menu";
const defWsCallback = (type: string, data: any) => {
console.log('接收到 WebSocket 消息, 默认处理函数:', type, data);
@ -210,11 +211,6 @@ export const useUserStore = defineStore({
if (value[AUTH_KEY]) {
this.setToken(value[AUTH_KEY])
}
authenticationApi({ userId: value.userId }).then(({ result }) => {
if (result) {
this.setAuth(result)
}
})
},
/**
* @description:
@ -224,6 +220,7 @@ export const useUserStore = defineStore({
this.setUser('')
this.setCurXs({})
this.setAuth([])
this.setChangeTime(''); // 清除权限变更时间,确保下次登录拉取最新菜单
this.setXsPickerInitialized(false); // 注销时重置学生选择器状态
this.exitWs();
this.wsCallback = defWsCallback;
@ -231,6 +228,7 @@ export const useUserStore = defineStore({
useDicStore().cleanData()
useCommonStore().cleanData();
useDataStore().cleanData();
useMenuStore().clearMenu(); // 清除菜单缓存
},
},
persist: {