build / build (push) Successful in 42s
- components/widgets:widgetRegistry(defineAsyncComponent 按需加载)+ EvaluateWidget/SyllabusWidget/WeekplanWidget,props widgetId、emit loaded、内部自行取数、ResizeObserver 自报真实高度;呈现只保留语义不逐像素复刻旧 html - views/index.vue:iframe 单分支改三分支(内置组件 / compType=2 走 :srcdoc + sandbox="allow-scripts allow-same-origin allow-forms"(不给 allow-top-navigation)/ 兜底「该小工具暂不可用」不白屏);:src="item.url" 与候选池 url 依赖删除;postMessage 身份下发只服务片段分支,高度统一收口 find.height - utils/widgetFragment.ts:wrapFragment 两段注入——取数桥在 head(早于片段自身脚本,否则 yhWidget undefined)、高度上报在 body 之后;</script> 拆拼防提前闭合门户脚本;节流用 setTimeout 尾沿 + 300/1200ms 兜底(iframe 隐藏期子文档不出动画帧,rAF 会把上报永久吞掉、帧高卡 min-height 撑出内层滚动);桥 URL 走 serviceHost 且自行解平台信封 data - views/Settings.vue:新增 admin pane「widget」(ADMIN_PANES/ALL_PANES/「系统」组导航项/v-else-if 链分支),普通用户导航隐藏且 URL 直达落 no-perm 黄条 - views/widget/WidgetManage.vue:双卡管理页(内置/自定义分组列表 + 名称/键/类型/data_code/排序/启用/sch_id 表单 + CodeMirror + 上传 .html 走 FileReader 填编辑器,不落地文件不产生 URL;内置条目 content 只读) - _widget.scss:--wg-* 六令牌 + 深玻璃 blur(18px) saturate(140%) + 描边 + 投影;拖拽态加深 blur(22px) 不再翻白;空态与 +/− 前景改走 token(配套 widget-add/sub/empty.svg 由硬编码色改 currentColor,widget-empty 原为内嵌 PNG 无法着色故换线性版);.widget-item 浅底深字保持不动 - UserSettingApi.ts:getWidgetData / getWidgetContent / GetWidgetCatalogList / SaveWidgetCatalog - 另含 src/store/index.ts 的 getWidgetAppIds 未配置态 .reverse()(非本会话所写,按用户确认一并提交:与 getWidgetAppList 降序比较器对齐,使未配置态按 widget_catalog.sort 正序渲染)
164 lines
5.9 KiB
TypeScript
164 lines
5.9 KiB
TypeScript
import { defineStore } from "pinia";
|
||
import Utils from "@/utils";
|
||
import { RoleInfo, UserSettingInfo, WidgetInfo, WidgetPosition } from "@/types";
|
||
import { flatten, indexOf, isNull, orderBy, pick, set } from "lodash";
|
||
import { BaseDict } from "@/types/Basics";
|
||
|
||
export interface IdefaultStore {
|
||
menuVisible: boolean;
|
||
userInfo: any;
|
||
curRoleInfo: RoleInfo;
|
||
userRoleList: Array<RoleInfo>;
|
||
curUserSettingInfo: UserSettingInfo;
|
||
curUserMenuList: Array<any>; //当前角色菜单
|
||
curUserAppList: Array<any>; //当前角色所有应用
|
||
/** 应用列表加载态(AppList 拉取时写入,Header 命令面板共享同一状态;2026-10-08) */
|
||
appListLoading: boolean;
|
||
curRoleUid: string | null; //当前角色uid
|
||
/** 未读消息数(msgCenter/summary 拉取 + WS newMessage 实时累加;Header 角标与 /msg 页左栏同源) */
|
||
unreadCount: number;
|
||
// curUsedAppList: Array<any>; //当前角色常用应用
|
||
}
|
||
|
||
const defaultRoleInfo = () => ({
|
||
roleId: 0,
|
||
roleName: "",
|
||
schId: 0,
|
||
schName: "",
|
||
childId: 0,
|
||
childName: "",
|
||
});
|
||
|
||
const defaultUserSettingInfo = () => ({
|
||
wallpaperUrl: "",
|
||
isWidgetShow: true,
|
||
widgetAppIds: "",
|
||
widgetAppList: [],
|
||
desktopAppList: [],
|
||
width: 380,
|
||
height: 300,
|
||
xaxis: 0,
|
||
yaxis: 0,
|
||
});
|
||
|
||
// currentYear: 0,
|
||
// currentSemester: null,
|
||
export const useDefaultStore = defineStore("defaultStore", {
|
||
state: (): IdefaultStore => {
|
||
return {
|
||
menuVisible: true,
|
||
userInfo: {},
|
||
curRoleInfo: defaultRoleInfo(),
|
||
curUserSettingInfo: defaultUserSettingInfo(),
|
||
userRoleList: [],
|
||
curUserAppList: [],
|
||
curUserMenuList: [],
|
||
curRoleUid: null,
|
||
unreadCount: 0,
|
||
appListLoading: false,
|
||
};
|
||
},
|
||
actions: {
|
||
setCurRoleInfo(info: RoleInfo) {
|
||
this.curRoleInfo = info;
|
||
},
|
||
setUnreadCount(count: number) {
|
||
this.unreadCount = Math.max(0, count || 0);
|
||
},
|
||
incUnread() {
|
||
this.unreadCount += 1;
|
||
},
|
||
decUnread() {
|
||
this.unreadCount = Math.max(0, this.unreadCount - 1);
|
||
},
|
||
setCurUserSettingsInfo(info: UserSettingInfo) {
|
||
this.curUserSettingInfo = info;
|
||
},
|
||
setCurUserAppList(apps: any[]) {
|
||
this.curUserAppList = apps;
|
||
},
|
||
setAppListLoading(v: boolean) {
|
||
this.appListLoading = v;
|
||
},
|
||
setCurUserMenuList(menus: any[]) {
|
||
this.curUserMenuList = menus;
|
||
},
|
||
updateWidgetInfo(info: WidgetPosition) {
|
||
Object.assign(this.curUserSettingInfo, info);
|
||
},
|
||
},
|
||
getters: {
|
||
getCurSchId(): number {
|
||
return this.curRoleInfo?.schId || -1;
|
||
},
|
||
getCurRoleId(): number {
|
||
return this.curRoleInfo?.roleId || -1;
|
||
},
|
||
getCurUserId(): number {
|
||
if (this.getCurRoleId == 3) {
|
||
if (!!this.curRoleInfo.childId) return this.curRoleInfo.childId;
|
||
}
|
||
return this.userInfo.id;
|
||
},
|
||
getCurWallPaperUrl(): any {
|
||
return this.curUserSettingInfo.wallpaperUrl;
|
||
},
|
||
getFlattenAppList(): any[] {
|
||
return flatten(this.curUserAppList.map(x => x.apps));
|
||
},
|
||
getIsAdmin() {
|
||
// const user: any = this.userInfo;
|
||
// if (user.type == 1) return true;
|
||
// if (typeof user.roleIds == "undefined" || user.roleIds == null) return false;
|
||
// let adminRoleList = user.roleList.filter((x: any) => [2, 5, 7].includes(x.roleId));
|
||
// return adminRoleList.findIndex((x: any) => x.schId == this.getCurSchId) > -1;
|
||
const user: any = this.userInfo;
|
||
if (user.type == 1) return true;
|
||
let roleId: number = this.getCurRoleId;
|
||
return [2, 5, 7].includes(roleId);
|
||
},
|
||
getWidgetSel(): BaseDict[] {
|
||
const { widgetAppList } = this.curUserSettingInfo;
|
||
let arr = widgetAppList.map(x => {
|
||
return { k: x.id, v: x.name, checked: this.getWidgetAppIds.includes(x.id) } as BaseDict;
|
||
});
|
||
return arr;
|
||
},
|
||
getWidgetAppIds() {
|
||
const { widgetAppIds: appIds, widgetAppList: appList } = this.curUserSettingInfo;
|
||
let checkIds: number[] = [];
|
||
// getWidgetAppList 的比较器按 appIds 降序渲染(新添加置顶),故未配置态需预反转,才与 widget_catalog.sort 正序一致
|
||
if (appIds == null) checkIds = appList.map(x => x.id).reverse();
|
||
else if (appIds.length == 0) checkIds = [];
|
||
else checkIds = appIds.split(",").map(x => parseInt(x));
|
||
return checkIds;
|
||
},
|
||
getWidgetAppList() {
|
||
const { widgetAppList: appList } = this.curUserSettingInfo;
|
||
const appIds: number[] = this.getWidgetAppIds;
|
||
let arr: any[] = appList
|
||
.filter(x => appIds.includes(x.id))
|
||
.sort((a: any, b: any) => {
|
||
return appIds.indexOf(b.id) - appIds.indexOf(a.id);
|
||
});
|
||
return arr;
|
||
},
|
||
getWidgetDragObj() {
|
||
let keys: Array<keyof WidgetInfo> = ["isWidgetShow", "xaxis", "yaxis", "width", "height"];
|
||
let dragObj: WidgetInfo = pick(this.curUserSettingInfo, keys);
|
||
let defaultObj = defaultUserSettingInfo();
|
||
if (dragObj.isWidgetShow == null) {
|
||
dragObj = pick(defaultObj, keys);
|
||
dragObj.isWidgetShow = true;
|
||
}
|
||
if (dragObj.xaxis === null || dragObj.yaxis == null) {
|
||
dragObj.xaxis = defaultObj.xaxis;
|
||
dragObj.yaxis = defaultObj.yaxis;
|
||
dragObj.width = defaultObj.width;
|
||
dragObj.height = defaultObj.height;
|
||
}
|
||
return dragObj;
|
||
},
|
||
},
|
||
});
|