bmp-layout 0.0.25-beta.11 → 0.0.25-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bmp-layout.es.js CHANGED
@@ -1302,6 +1302,26 @@ const usePermissionStore = defineStore("layout-permission", {
1302
1302
  },
1303
1303
  getModuleName() {
1304
1304
  return this.moduleName;
1305
+ },
1306
+ /**
1307
+ * 获取当前用户已授权的所有菜单 ID 集合
1308
+ * 递归遍历 roleRouters 树形结构,提取所有菜单的 id
1309
+ * @returns {Set<string>} 已授权的菜单 ID 集合
1310
+ */
1311
+ getGrantedMenuIds() {
1312
+ const ids = /* @__PURE__ */ new Set();
1313
+ const traverse = (menus) => {
1314
+ if (!Array.isArray(menus))
1315
+ return;
1316
+ for (const menu of menus) {
1317
+ if (menu.id)
1318
+ ids.add(String(menu.id));
1319
+ if (menu.children)
1320
+ traverse(menu.children);
1321
+ }
1322
+ };
1323
+ traverse(this.roleRouters);
1324
+ return ids;
1305
1325
  }
1306
1326
  },
1307
1327
  actions: {
@@ -8588,11 +8608,236 @@ const _sfc_main$s = /* @__PURE__ */ Object.assign({ name: "MenuTrigger" }, {
8588
8608
  }
8589
8609
  });
8590
8610
  const MenuTrigger = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["__scopeId", "data-v-df837f35"]]);
8611
+ const useFavoriteStore = defineStore("layout-favorite", {
8612
+ state: () => ({
8613
+ /**
8614
+ * 收藏列表(后端 /list 返回结构:menuId, menuName, leafPath, moduleId, modulePath, moduleName, isFavorite=true, createTime)
8615
+ */
8616
+ favorites: [],
8617
+ /**
8618
+ * 最近使用列表(后端 /list 返回结构:menuId, menuName, leafPath, moduleId, modulePath, moduleName, isFavorite, visitCount, lastVisitTime)
8619
+ */
8620
+ recents: [],
8621
+ /**
8622
+ * 已收藏菜单ID集合(Set,用于所有位置快速判断是否已收藏)
8623
+ */
8624
+ favoriteSet: /* @__PURE__ */ new Set(),
8625
+ /**
8626
+ * 是否已初始化拉取过数据(防止重复请求)
8627
+ */
8628
+ loaded: false,
8629
+ /**
8630
+ * 当前正在执行的收藏操作ID集合(防抖/防重复点击)
8631
+ */
8632
+ loadingIds: /* @__PURE__ */ new Set()
8633
+ }),
8634
+ getters: {
8635
+ /**
8636
+ * 获取当前用户已授权的菜单 ID 集合(从 permissionStore 读取)
8637
+ */
8638
+ grantedMenuIds() {
8639
+ const permissionStore = usePermissionStore();
8640
+ return permissionStore.getGrantedMenuIds;
8641
+ },
8642
+ /**
8643
+ * 收藏列表(对外只读,已过滤无权限菜单)
8644
+ */
8645
+ getFavorites() {
8646
+ const granted = this.grantedMenuIds;
8647
+ return this.favorites.filter((item) => granted.has(String(item.menuId)));
8648
+ },
8649
+ /**
8650
+ * 最近使用列表(已过滤无权限菜单,isFavorite 实时派生)
8651
+ * 注意:返回的是新数组,不直接修改 state
8652
+ */
8653
+ getRecents() {
8654
+ const granted = this.grantedMenuIds;
8655
+ return this.recents.filter((item) => granted.has(String(item.menuId))).map((item) => ({
8656
+ ...item,
8657
+ isFavorite: this.favoriteSet.has(item.menuId)
8658
+ }));
8659
+ },
8660
+ /**
8661
+ * 收藏集合(用于快速判断)
8662
+ */
8663
+ getFavoriteSet() {
8664
+ return this.favoriteSet;
8665
+ },
8666
+ /**
8667
+ * 是否已加载
8668
+ */
8669
+ isLoaded() {
8670
+ return () => this.loaded;
8671
+ },
8672
+ /**
8673
+ * 检查指定菜单是否已收藏
8674
+ */
8675
+ isFavorite() {
8676
+ return (menuId) => this.favoriteSet.has(String(menuId));
8677
+ },
8678
+ /**
8679
+ * 检查指定菜单是否正在收藏操作中
8680
+ */
8681
+ isLoading() {
8682
+ return (menuId) => this.loadingIds.has(String(menuId));
8683
+ }
8684
+ },
8685
+ actions: {
8686
+ // ==================== 由宿主项目调用 ====================
8687
+ /**
8688
+ * 初始化收藏列表(宿主在接口返回成功后调用一次)
8689
+ * @param {Array} list 后端返回的收藏列表
8690
+ */
8691
+ initFavorites(list) {
8692
+ this.favorites = Array.isArray(list) ? list : [];
8693
+ this.favoriteSet = new Set(this.favorites.map((item) => String(item.menuId)));
8694
+ this.loaded = true;
8695
+ },
8696
+ /**
8697
+ * 初始化最近使用列表(宿主在接口返回成功后调用一次)
8698
+ * @param {Array} list 后端返回的最近使用列表
8699
+ */
8700
+ initRecents(list) {
8701
+ this.recents = Array.isArray(list) ? list.map((item) => ({
8702
+ ...item,
8703
+ isFavorite: this.favoriteSet.has(String(item.menuId))
8704
+ })) : [];
8705
+ },
8706
+ // ==================== 由 ProductServicePanel 调用 ====================
8707
+ /**
8708
+ * 标记收藏操作开始(加 loading)
8709
+ * @param {String} menuId 菜单ID
8710
+ */
8711
+ startLoading(menuId) {
8712
+ this.loadingIds.add(String(menuId));
8713
+ },
8714
+ /**
8715
+ * 标记收藏操作结束(移除 loading)
8716
+ * @param {String} menuId 菜单ID
8717
+ */
8718
+ stopLoading(menuId) {
8719
+ this.loadingIds.delete(String(menuId));
8720
+ },
8721
+ /**
8722
+ * 本地添加一条收藏(宿主在接口成功后调用)
8723
+ *
8724
+ * 注意:本方法不会发起 HTTP 请求,由宿主项目调接口后手动调用。
8725
+ * 如果记录已存在则静默返回。
8726
+ *
8727
+ * @param {Object} record 收藏记录(需包含 menuId, menuName, leafPath, moduleId, modulePath, moduleName)
8728
+ */
8729
+ addFavorite(record) {
8730
+ if (!record || !record.menuId)
8731
+ return;
8732
+ const menuId = String(record.menuId);
8733
+ if (this.favoriteSet.has(menuId))
8734
+ return;
8735
+ const newFavorite = {
8736
+ menuId: record.menuId,
8737
+ menuName: record.menuName,
8738
+ leafPath: record.leafPath,
8739
+ moduleId: record.moduleId,
8740
+ modulePath: record.modulePath,
8741
+ moduleName: record.moduleName,
8742
+ isFavorite: true,
8743
+ createTime: record.createTime || (/* @__PURE__ */ new Date()).toISOString()
8744
+ };
8745
+ this.favorites = [newFavorite, ...this.favorites];
8746
+ this.favoriteSet.add(menuId);
8747
+ },
8748
+ /**
8749
+ * 本地移除一条收藏(宿主在接口成功后调用)
8750
+ * @param {String} menuId 菜单ID
8751
+ */
8752
+ cancelFavorite(menuId) {
8753
+ if (!menuId)
8754
+ return;
8755
+ const menuIdStr = String(menuId);
8756
+ this.favorites = this.favorites.filter((item) => String(item.menuId) !== menuIdStr);
8757
+ this.favoriteSet.delete(menuIdStr);
8758
+ },
8759
+ /**
8760
+ * 更新最近使用的访问计数(宿主在接口成功后调用)
8761
+ *
8762
+ * 存在则 visitCount+1 并重排到第一位,不存在则插入一条新记录到第一位
8763
+ *
8764
+ * @param {Object} record 最近使用记录
8765
+ */
8766
+ bumpVisitCount(record) {
8767
+ if (!record || !record.menuId)
8768
+ return;
8769
+ const menuIdStr = String(record.menuId);
8770
+ const idx = this.recents.findIndex((item) => String(item.menuId) === menuIdStr);
8771
+ if (idx !== -1) {
8772
+ const updated = {
8773
+ ...this.recents[idx],
8774
+ visitCount: (this.recents[idx].visitCount || 0) + 1,
8775
+ lastVisitTime: (/* @__PURE__ */ new Date()).toISOString(),
8776
+ isFavorite: this.favoriteSet.has(menuIdStr)
8777
+ };
8778
+ const newList = [...this.recents];
8779
+ newList.splice(idx, 1);
8780
+ newList.unshift(updated);
8781
+ this.recents = newList;
8782
+ } else {
8783
+ this.recents = [
8784
+ {
8785
+ menuId: record.menuId,
8786
+ menuName: record.menuName,
8787
+ leafPath: record.leafPath,
8788
+ moduleId: record.moduleId,
8789
+ modulePath: record.modulePath,
8790
+ moduleName: record.moduleName,
8791
+ isFavorite: this.favoriteSet.has(menuIdStr),
8792
+ visitCount: 1,
8793
+ lastVisitTime: (/* @__PURE__ */ new Date()).toISOString()
8794
+ },
8795
+ ...this.recents
8796
+ ];
8797
+ }
8798
+ },
8799
+ /**
8800
+ * 切换菜单的收藏状态(根据当前状态自动 add 或 cancel 本地)
8801
+ * 注意:本方法只操作本地状态,HTTP 由宿主项目负责
8802
+ *
8803
+ * @param {Object} record 菜单记录
8804
+ * @returns {Boolean} true=已收藏,false=已取消
8805
+ */
8806
+ toggleFavoriteLocal(record) {
8807
+ const menuId = String(record.menuId);
8808
+ if (this.favoriteSet.has(menuId)) {
8809
+ this.cancelFavorite(menuId);
8810
+ return false;
8811
+ } else {
8812
+ this.addFavorite(record);
8813
+ return true;
8814
+ }
8815
+ },
8816
+ /**
8817
+ * 重置 store(用户登出时调用)
8818
+ */
8819
+ resetState() {
8820
+ this.favorites = [];
8821
+ this.recents = [];
8822
+ this.favoriteSet = /* @__PURE__ */ new Set();
8823
+ this.loaded = false;
8824
+ this.loadingIds = /* @__PURE__ */ new Set();
8825
+ }
8826
+ },
8827
+ persist: false
8828
+ });
8829
+ const useFavoriteStoreWithOut = () => {
8830
+ return useFavoriteStore(store);
8831
+ };
8591
8832
  const _hoisted_1$b = { class: "sidebar-inner" };
8592
8833
  const _hoisted_2$9 = ["onClick"];
8593
8834
  const _hoisted_3$8 = ["onClick"];
8594
8835
  const _hoisted_4$7 = ["onClick"];
8595
8836
  const _hoisted_5$6 = ["onClick"];
8837
+ const _hoisted_6$5 = ["onClick"];
8838
+ const _hoisted_7$3 = ["onClick"];
8839
+ const RECENT_DISPLAY_LIMIT = 20;
8840
+ const TRACK_DEBOUNCE_MS = 3e3;
8596
8841
  const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel" }, {
8597
8842
  __name: "ProductServicePanel",
8598
8843
  props: {
@@ -8601,7 +8846,17 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8601
8846
  default: false
8602
8847
  }
8603
8848
  },
8604
- emits: ["update:visible", "select"],
8849
+ emits: [
8850
+ "update:visible",
8851
+ "select",
8852
+ // 菜单收藏相关事件(宿主监听后调接口,完成后同步 store)
8853
+ "menu-favorite-add",
8854
+ // 添加收藏,参数:menu record 对象
8855
+ "menu-favorite-cancel",
8856
+ // 取消收藏,参数:menuId (String)
8857
+ "menu-recent-track"
8858
+ // 记录菜单访问,参数:完整 menu record 对象(含 menuId, menuName, leafPath, moduleId, modulePath, moduleName)
8859
+ ],
8605
8860
  setup(__props, { emit: __emit }) {
8606
8861
  const { getPrefixCls: getPrefixCls2 } = useDesign();
8607
8862
  const prefixCls2 = getPrefixCls2("product-service-panel");
@@ -8610,6 +8865,7 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8610
8865
  const emit = __emit;
8611
8866
  const router = useRouter();
8612
8867
  const permissionStore = usePermissionStore();
8868
+ const favoriteStore = useFavoriteStore();
8613
8869
  const getMenuTitle = (item) => {
8614
8870
  var _a2;
8615
8871
  const rawTitle = ((_a2 = item.meta) == null ? void 0 : _a2.title) || item.name || "";
@@ -8695,16 +8951,117 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8695
8951
  return [];
8696
8952
  const thirdMenus = (activeModule.value.children || []).filter(isVisible);
8697
8953
  return thirdMenus.map((third) => ({
8698
- id: third.id,
8954
+ // 使用 extractMenuId 多源提取(宿主路由数据中 id 可能位于不同层级)
8955
+ id: extractMenuId(third),
8699
8956
  title: getMenuTitle(third),
8700
8957
  path: third.path,
8701
8958
  items: (third.children || []).filter(isVisible).map((fourth) => ({
8702
- id: fourth.id,
8959
+ id: extractMenuId(fourth),
8703
8960
  title: getMenuTitle(fourth),
8704
8961
  path: fourth.path
8705
8962
  }))
8706
8963
  }));
8707
8964
  });
8965
+ const isFavoriteView = computed(() => activeProductIndex.value === -1);
8966
+ const favoriteList = computed(() => favoriteStore.getFavorites);
8967
+ const recentList = computed(() => favoriteStore.getRecents.slice(0, RECENT_DISPLAY_LIMIT));
8968
+ const isFavoriteLoading = (menuId) => favoriteStore.isLoading(String(menuId));
8969
+ const isFavorite = (menuId) => favoriteStore.isFavorite(String(menuId));
8970
+ const lastTrackMap = /* @__PURE__ */ new Map();
8971
+ const emitMenuTrack = (record) => {
8972
+ if (!record || !record.menuId)
8973
+ return;
8974
+ const menuIdStr = String(record.menuId);
8975
+ const now = Date.now();
8976
+ const last = lastTrackMap.get(menuIdStr) || 0;
8977
+ if (now - last < TRACK_DEBOUNCE_MS)
8978
+ return;
8979
+ lastTrackMap.set(menuIdStr, now);
8980
+ emit("menu-recent-track", record);
8981
+ };
8982
+ const handleAddFavorite = (record) => {
8983
+ if (!record || !record.menuId || record.menuId === "undefined") {
8984
+ console.warn("[ProductServicePanel] 无法收藏:缺少有效 menuId", record);
8985
+ return;
8986
+ }
8987
+ if (isFavoriteLoading(record.menuId))
8988
+ return;
8989
+ favoriteStore.startLoading(record.menuId);
8990
+ emit("menu-favorite-add", record);
8991
+ };
8992
+ const handleCancelFavorite = (menuId) => {
8993
+ if (!menuId || String(menuId) === "undefined") {
8994
+ console.warn("[ProductServicePanel] 无法取消收藏:缺少有效 menuId");
8995
+ return;
8996
+ }
8997
+ if (isFavoriteLoading(menuId))
8998
+ return;
8999
+ favoriteStore.startLoading(menuId);
9000
+ emit("menu-favorite-cancel", String(menuId));
9001
+ };
9002
+ const handleFavoriteNavigate = (record, trackVisit = true) => {
9003
+ if (!record || !record.leafPath)
9004
+ return;
9005
+ const currentModuleId = permissionStore.getModuleId;
9006
+ const modulePath = record.modulePath === "/" ? "" : record.modulePath || "";
9007
+ const leafPath = record.leafPath || "";
9008
+ if (record.moduleId === currentModuleId) {
9009
+ const normalizedLeaf = leafPath.startsWith("/") ? leafPath : `/${leafPath}`;
9010
+ router.push(normalizedLeaf);
9011
+ if (trackVisit)
9012
+ emitMenuTrack(record);
9013
+ closePanel();
9014
+ return;
9015
+ }
9016
+ const currentOrigin = window.location.origin;
9017
+ let finalPath = leafPath;
9018
+ if (modulePath) {
9019
+ const hasPrefix = finalPath === modulePath || finalPath.startsWith(modulePath + "/");
9020
+ finalPath = hasPrefix ? finalPath : `${modulePath}/${finalPath.replace(/^\//, "")}`;
9021
+ }
9022
+ const targetUrl = `${currentOrigin}${finalPath.startsWith("/") ? finalPath : `/${finalPath}`}`;
9023
+ window.location.href = targetUrl;
9024
+ if (trackVisit)
9025
+ emitMenuTrack(record);
9026
+ closePanel();
9027
+ };
9028
+ const extractMenuId = (item) => {
9029
+ var _a2;
9030
+ if (!item)
9031
+ return "";
9032
+ const rawId = item.id ?? ((_a2 = item.meta) == null ? void 0 : _a2.id) ?? item.menuId ?? item.name;
9033
+ if (rawId == null || rawId === "" || rawId === "undefined")
9034
+ return "";
9035
+ return String(rawId);
9036
+ };
9037
+ const buildFavoriteRecord = (leafItem, group, activeModule2, activeProduct2) => {
9038
+ const parentParts = [];
9039
+ if (activeProduct2 == null ? void 0 : activeProduct2.path)
9040
+ parentParts.push(activeProduct2.path);
9041
+ if (activeModule2 == null ? void 0 : activeModule2.path)
9042
+ parentParts.push(activeModule2.path);
9043
+ if (group == null ? void 0 : group.path)
9044
+ parentParts.push(group.path);
9045
+ const parentPath = parentParts.join("/");
9046
+ const menuId = extractMenuId(leafItem);
9047
+ if (!menuId) {
9048
+ console.warn("[ProductServicePanel] 无法收藏:菜单ID提取失败", leafItem);
9049
+ return null;
9050
+ }
9051
+ const fullLeafPath = joinPath(parentPath, leafItem.path);
9052
+ return {
9053
+ menuId,
9054
+ menuName: leafItem.title || leafItem.menuName || getMenuTitle(leafItem),
9055
+ leafPath: fullLeafPath,
9056
+ parentPath,
9057
+ moduleId: extractMenuId(activeModule2),
9058
+ modulePath: activeModule2 == null ? void 0 : activeModule2.modulePath,
9059
+ moduleName: (activeModule2 == null ? void 0 : activeModule2.title) || (activeModule2 == null ? void 0 : activeModule2.moduleName)
9060
+ };
9061
+ };
9062
+ const buildTrackRecord = (leafItem, group, activeModule2, activeProduct2) => {
9063
+ return buildFavoriteRecord(leafItem, group, activeModule2, activeProduct2);
9064
+ };
8708
9065
  const joinPath = (...paths) => {
8709
9066
  return paths.filter(Boolean).reduce((result, path) => {
8710
9067
  if (!result)
@@ -8755,7 +9112,8 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8755
9112
  }
8756
9113
  };
8757
9114
  const handleProductSelect = (index) => {
8758
- activeProductIndex.value = index;
9115
+ const safeIndex = typeof index === "number" && index >= 0 ? index : 0;
9116
+ activeProductIndex.value = safeIndex;
8759
9117
  activeModuleIndex.value = 0;
8760
9118
  };
8761
9119
  const handleModuleSelect = (index) => {
@@ -8763,14 +9121,23 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8763
9121
  };
8764
9122
  const handleItemClick = (fourthItem, group) => {
8765
9123
  var _a2, _b;
9124
+ const trackRecord = buildTrackRecord(fourthItem, group, activeModule.value, activeProduct.value);
9125
+ emitMenuTrack(trackRecord);
8766
9126
  const parentPath = joinPath((_a2 = activeProduct.value) == null ? void 0 : _a2.path, (_b = activeModule.value) == null ? void 0 : _b.path, group.path);
8767
9127
  handleSelect(fourthItem, parentPath);
8768
9128
  };
8769
9129
  const handleGroupClick = (group) => {
8770
9130
  var _a2, _b;
9131
+ const trackRecord = buildTrackRecord(group, group, activeModule.value, activeProduct.value);
9132
+ emitMenuTrack(trackRecord);
8771
9133
  const parentPath = joinPath((_a2 = activeProduct.value) == null ? void 0 : _a2.path, (_b = activeModule.value) == null ? void 0 : _b.path);
8772
9134
  handleSelect({ path: group.path, children: [] }, parentPath);
8773
9135
  };
9136
+ const handleCommonSelect = () => {
9137
+ activeProductIndex.value = -1;
9138
+ activeModuleIndex.value = 0;
9139
+ expandedCardIndex.value = null;
9140
+ };
8774
9141
  const syncActiveSelection = () => {
8775
9142
  const currentModuleId = permissionStore.getModuleId;
8776
9143
  if (!currentModuleId)
@@ -8818,7 +9185,9 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8818
9185
  closePanel();
8819
9186
  }
8820
9187
  };
8821
- onMounted(() => document.addEventListener("keydown", handleKeydown));
9188
+ onMounted(() => {
9189
+ document.addEventListener("keydown", handleKeydown);
9190
+ });
8822
9191
  onUnmounted(() => document.removeEventListener("keydown", handleKeydown));
8823
9192
  return (_ctx, _cache) => {
8824
9193
  return openBlock(), createBlock(Teleport, { to: "body" }, [
@@ -8851,12 +9220,30 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8851
9220
  createVNode(unref(ElScrollbar), null, {
8852
9221
  default: withCtx(() => [
8853
9222
  createElementVNode("div", _hoisted_1$b, [
9223
+ createElementVNode("div", {
9224
+ class: normalizeClass([
9225
+ unref(prefixCls2) + "__product-card",
9226
+ unref(prefixCls2) + "__product-card--common",
9227
+ { "is-active": activeProductIndex.value === -1 }
9228
+ ]),
9229
+ onClick: handleCommonSelect
9230
+ }, [
9231
+ createElementVNode("div", {
9232
+ class: normalizeClass([unref(prefixCls2) + "__product-name"])
9233
+ }, [
9234
+ createVNode(unref(_sfc_main$x), {
9235
+ icon: "svg-icon:favorite-filled",
9236
+ size: 16
9237
+ }),
9238
+ createElementVNode("span", null, toDisplayString(unref(t2)("layout.common.commonGroup")), 1)
9239
+ ], 2)
9240
+ ], 2),
8854
9241
  (openBlock(true), createElementBlock(Fragment, null, renderList(productList.value, (product, pIndex) => {
8855
9242
  return openBlock(), createElementBlock("div", {
8856
9243
  key: product.id || pIndex,
8857
9244
  class: normalizeClass([
8858
9245
  unref(prefixCls2) + "__product-card",
8859
- { "is-active": activeProductIndex.value === pIndex },
9246
+ { "is-active": activeProductIndex.value === pIndex && activeProductIndex.value !== -1 },
8860
9247
  { "is-expanded": expandedCardIndex.value === pIndex }
8861
9248
  ]),
8862
9249
  onClick: ($event) => {
@@ -8894,7 +9281,7 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8894
9281
  class: normalizeClass([
8895
9282
  unref(prefixCls2) + "__module-tag",
8896
9283
  {
8897
- "is-active": activeProductIndex.value === pIndex && activeModuleIndex.value === mIndex
9284
+ "is-active": activeProductIndex.value === pIndex && activeModuleIndex.value === mIndex && activeProductIndex.value !== -1
8898
9285
  }
8899
9286
  ]),
8900
9287
  onClick: withModifiers(($event) => (handleProductSelect(pIndex), handleModuleSelect(mIndex)), ["stop"])
@@ -8946,7 +9333,109 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8946
9333
  createElementVNode("div", {
8947
9334
  class: normalizeClass([unref(prefixCls2) + "__grid-container"])
8948
9335
  }, [
8949
- contentGroups.value.length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(contentGroups.value, (group) => {
9336
+ isFavoriteView.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
9337
+ createElementVNode("div", {
9338
+ class: normalizeClass([unref(prefixCls2) + "__group"])
9339
+ }, [
9340
+ createElementVNode("div", {
9341
+ class: normalizeClass([unref(prefixCls2) + "__group-title"])
9342
+ }, [
9343
+ createElementVNode("span", null, toDisplayString(unref(t2)("layout.common.myFavorites")), 1)
9344
+ ], 2),
9345
+ favoriteList.value.length > 0 ? (openBlock(), createElementBlock("div", {
9346
+ key: 0,
9347
+ class: normalizeClass([unref(prefixCls2) + "__group-grid"])
9348
+ }, [
9349
+ (openBlock(true), createElementBlock(Fragment, null, renderList(favoriteList.value, (fav) => {
9350
+ return openBlock(), createElementBlock("div", {
9351
+ key: "fav-" + fav.menuId,
9352
+ class: normalizeClass([unref(prefixCls2) + "__group-item"])
9353
+ }, [
9354
+ createElementVNode("span", {
9355
+ class: normalizeClass([unref(prefixCls2) + "__group-item-title"]),
9356
+ onClick: ($event) => handleFavoriteNavigate(fav, true)
9357
+ }, toDisplayString(fav.menuName), 11, _hoisted_4$7),
9358
+ !isFavoriteLoading(fav.menuId) ? (openBlock(), createBlock(unref(_sfc_main$x), {
9359
+ key: 0,
9360
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-active"]),
9361
+ icon: "svg-icon:favorite-filled",
9362
+ size: 14,
9363
+ onClick: withModifiers(($event) => handleCancelFavorite(fav.menuId), ["stop"])
9364
+ }, null, 8, ["class", "onClick"])) : (openBlock(), createBlock(unref(_sfc_main$x), {
9365
+ key: 1,
9366
+ icon: "ep:loading",
9367
+ size: 14,
9368
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-loading"])
9369
+ }, null, 8, ["class"]))
9370
+ ], 2);
9371
+ }), 128))
9372
+ ], 2)) : (openBlock(), createElementBlock("div", {
9373
+ key: 1,
9374
+ class: normalizeClass([unref(prefixCls2) + "__group-empty-hint"])
9375
+ }, [
9376
+ createVNode(unref(_sfc_main$x), {
9377
+ icon: "svg-icon:favorite-outline",
9378
+ size: 16
9379
+ }),
9380
+ createElementVNode("span", null, toDisplayString(unref(t2)("layout.common.noFavoritesHint")), 1)
9381
+ ], 2))
9382
+ ], 2),
9383
+ createElementVNode("div", {
9384
+ class: normalizeClass([unref(prefixCls2) + "__group"]),
9385
+ style: { "margin-top": "24px" }
9386
+ }, [
9387
+ createElementVNode("div", {
9388
+ class: normalizeClass([unref(prefixCls2) + "__group-title"])
9389
+ }, [
9390
+ createElementVNode("span", null, toDisplayString(unref(t2)("layout.common.recentUsed")), 1)
9391
+ ], 2),
9392
+ recentList.value.length > 0 ? (openBlock(), createElementBlock("div", {
9393
+ key: 0,
9394
+ class: normalizeClass([unref(prefixCls2) + "__group-grid"])
9395
+ }, [
9396
+ (openBlock(true), createElementBlock(Fragment, null, renderList(recentList.value, (rec) => {
9397
+ return openBlock(), createElementBlock("div", {
9398
+ key: "rec-" + rec.menuId,
9399
+ class: normalizeClass([unref(prefixCls2) + "__group-item"])
9400
+ }, [
9401
+ createElementVNode("span", {
9402
+ class: normalizeClass([unref(prefixCls2) + "__group-item-title"]),
9403
+ onClick: ($event) => handleFavoriteNavigate(rec, false)
9404
+ }, toDisplayString(rec.menuName), 11, _hoisted_5$6),
9405
+ !isFavoriteLoading(rec.menuId) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
9406
+ isFavorite(rec.menuId) ? (openBlock(), createBlock(unref(_sfc_main$x), {
9407
+ key: 0,
9408
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-active"]),
9409
+ icon: "svg-icon:favorite-filled",
9410
+ size: 14,
9411
+ onClick: withModifiers(($event) => handleCancelFavorite(rec.menuId), ["stop"])
9412
+ }, null, 8, ["class", "onClick"])) : (openBlock(), createBlock(unref(_sfc_main$x), {
9413
+ key: 1,
9414
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon"]),
9415
+ icon: "svg-icon:favorite-outline",
9416
+ size: 14,
9417
+ onClick: withModifiers(($event) => handleAddFavorite(rec), ["stop"])
9418
+ }, null, 8, ["class", "onClick"]))
9419
+ ], 64)) : (openBlock(), createBlock(unref(_sfc_main$x), {
9420
+ key: 1,
9421
+ icon: "ep:loading",
9422
+ size: 14,
9423
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-loading"])
9424
+ }, null, 8, ["class"]))
9425
+ ], 2);
9426
+ }), 128))
9427
+ ], 2)) : (openBlock(), createElementBlock("div", {
9428
+ key: 1,
9429
+ class: normalizeClass([unref(prefixCls2) + "__group-empty-hint"])
9430
+ }, [
9431
+ createVNode(unref(_sfc_main$x), {
9432
+ icon: "ant-design:inbox-outlined",
9433
+ size: 16
9434
+ }),
9435
+ createElementVNode("span", null, toDisplayString(unref(t2)("layout.common.noRecentHint")), 1)
9436
+ ], 2))
9437
+ ], 2)
9438
+ ], 64)) : contentGroups.value.length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(contentGroups.value, (group) => {
8950
9439
  return openBlock(), createElementBlock("div", {
8951
9440
  key: group.id || group.title,
8952
9441
  class: normalizeClass([unref(prefixCls2) + "__group"])
@@ -8962,22 +9451,66 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
8962
9451
  group.items.length > 0 ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(group.items, (item) => {
8963
9452
  return openBlock(), createElementBlock("div", {
8964
9453
  key: item.id || item.path,
8965
- class: normalizeClass([unref(prefixCls2) + "__group-item"]),
8966
- onClick: ($event) => handleItemClick(item, group)
9454
+ class: normalizeClass([unref(prefixCls2) + "__group-item"])
8967
9455
  }, [
8968
- createElementVNode("span", null, toDisplayString(item.title), 1)
8969
- ], 10, _hoisted_4$7);
9456
+ createElementVNode("span", {
9457
+ class: normalizeClass([unref(prefixCls2) + "__group-item-title"]),
9458
+ onClick: ($event) => handleItemClick(item, group)
9459
+ }, toDisplayString(item.title), 11, _hoisted_6$5),
9460
+ !isFavoriteLoading(item.id) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
9461
+ isFavorite(item.id) ? (openBlock(), createBlock(unref(_sfc_main$x), {
9462
+ key: 0,
9463
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-active"]),
9464
+ icon: "svg-icon:favorite-filled",
9465
+ size: 14,
9466
+ onClick: withModifiers(($event) => handleCancelFavorite(item.id), ["stop"])
9467
+ }, null, 8, ["class", "onClick"])) : (openBlock(), createBlock(unref(_sfc_main$x), {
9468
+ key: 1,
9469
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon"]),
9470
+ icon: "svg-icon:favorite-outline",
9471
+ size: 14,
9472
+ onClick: withModifiers(($event) => handleAddFavorite(buildFavoriteRecord(item, group, activeModule.value, activeProduct.value)), ["stop"])
9473
+ }, null, 8, ["class", "onClick"]))
9474
+ ], 64)) : (openBlock(), createBlock(unref(_sfc_main$x), {
9475
+ key: 1,
9476
+ icon: "ep:loading",
9477
+ size: 14,
9478
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-loading"])
9479
+ }, null, 8, ["class"]))
9480
+ ], 2);
8970
9481
  }), 128)) : (openBlock(), createElementBlock("div", {
8971
9482
  key: 1,
8972
- class: normalizeClass([unref(prefixCls2) + "__group-item"]),
8973
- onClick: ($event) => handleGroupClick(group)
9483
+ class: normalizeClass([unref(prefixCls2) + "__group-item"])
8974
9484
  }, [
8975
- createElementVNode("span", null, toDisplayString(group.title), 1)
8976
- ], 10, _hoisted_5$6))
9485
+ createElementVNode("span", {
9486
+ class: normalizeClass([unref(prefixCls2) + "__group-item-title"]),
9487
+ onClick: ($event) => handleGroupClick(group)
9488
+ }, toDisplayString(group.title), 11, _hoisted_7$3),
9489
+ !isFavoriteLoading(group.id) ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
9490
+ isFavorite(group.id) ? (openBlock(), createBlock(unref(_sfc_main$x), {
9491
+ key: 0,
9492
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-active"]),
9493
+ icon: "svg-icon:favorite-filled",
9494
+ size: 14,
9495
+ onClick: withModifiers(($event) => handleCancelFavorite(group.id), ["stop"])
9496
+ }, null, 8, ["class", "onClick"])) : (openBlock(), createBlock(unref(_sfc_main$x), {
9497
+ key: 1,
9498
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon"]),
9499
+ icon: "svg-icon:favorite-outline",
9500
+ size: 14,
9501
+ onClick: withModifiers(($event) => handleAddFavorite(buildFavoriteRecord(group, group, activeModule.value, activeProduct.value)), ["stop"])
9502
+ }, null, 8, ["class", "onClick"]))
9503
+ ], 64)) : (openBlock(), createBlock(unref(_sfc_main$x), {
9504
+ key: 1,
9505
+ icon: "ep:loading",
9506
+ size: 14,
9507
+ class: normalizeClass([unref(prefixCls2) + "__favorite-icon", "is-loading"])
9508
+ }, null, 8, ["class"]))
9509
+ ], 2))
8977
9510
  ], 2)
8978
9511
  ], 2);
8979
9512
  }), 128)) : activeProduct.value ? (openBlock(), createElementBlock("div", {
8980
- key: 1,
9513
+ key: 2,
8981
9514
  class: normalizeClass([unref(prefixCls2) + "__empty"])
8982
9515
  }, [
8983
9516
  createVNode(unref(_sfc_main$x), {
@@ -9004,10 +9537,16 @@ const _sfc_main$r = /* @__PURE__ */ Object.assign({ name: "ProductServicePanel"
9004
9537
  };
9005
9538
  }
9006
9539
  });
9007
- const ProductServicePanel = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-f9a0a896"]]);
9540
+ const ProductServicePanel = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["__scopeId", "data-v-ce97e192"]]);
9008
9541
  const _sfc_main$q = /* @__PURE__ */ Object.assign({ name: "Logo" }, {
9009
9542
  __name: "Logo",
9010
- emits: ["logo-click"],
9543
+ emits: [
9544
+ "logo-click",
9545
+ // 转发 ProductServicePanel 的菜单收藏事件
9546
+ "menu-favorite-add",
9547
+ "menu-favorite-cancel",
9548
+ "menu-recent-track"
9549
+ ],
9011
9550
  setup(__props, { emit: __emit }) {
9012
9551
  const emit = __emit;
9013
9552
  const { getPrefixCls: getPrefixCls2 } = useDesign();
@@ -9054,7 +9593,10 @@ const _sfc_main$q = /* @__PURE__ */ Object.assign({ name: "Logo" }, {
9054
9593
  ], 2),
9055
9594
  createVNode(unref(ProductServicePanel), {
9056
9595
  visible: panelVisible.value,
9057
- "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => panelVisible.value = $event)
9596
+ "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => panelVisible.value = $event),
9597
+ onMenuFavoriteAdd: _cache[1] || (_cache[1] = (record) => emit("menu-favorite-add", record)),
9598
+ onMenuFavoriteCancel: _cache[2] || (_cache[2] = (menuId) => emit("menu-favorite-cancel", menuId)),
9599
+ onMenuRecentTrack: _cache[3] || (_cache[3] = (menuId) => emit("menu-recent-track", menuId))
9058
9600
  }, null, 8, ["visible"])
9059
9601
  ]);
9060
9602
  };
@@ -9121,31 +9663,18 @@ const _sfc_main$o = /* @__PURE__ */ Object.assign({ name: "Message" }, {
9121
9663
  color: {
9122
9664
  type: String,
9123
9665
  default: ""
9666
+ },
9667
+ unreadCount: {
9668
+ type: Number,
9669
+ default: 0
9124
9670
  }
9125
9671
  },
9126
9672
  emits: ["message-click"],
9127
9673
  setup(__props, { emit: __emit }) {
9128
9674
  const emit = __emit;
9129
- const userStore = useUserStoreWithOut();
9130
- const unreadCount = ref(0);
9131
- const getUnreadCount = async () => {
9132
- };
9133
9675
  const handleMessageClick = () => {
9134
9676
  emit("message-click");
9135
9677
  };
9136
- onMounted(() => {
9137
- getUnreadCount();
9138
- setInterval(
9139
- () => {
9140
- if (userStore.getIsSetUser) {
9141
- getUnreadCount();
9142
- } else {
9143
- unreadCount.value = 0;
9144
- }
9145
- },
9146
- 1e3 * 60 * 2
9147
- );
9148
- });
9149
9678
  return (_ctx, _cache) => {
9150
9679
  const _component_Icon = resolveComponent("Icon");
9151
9680
  return openBlock(), createElementBlock("div", {
@@ -9153,7 +9682,8 @@ const _sfc_main$o = /* @__PURE__ */ Object.assign({ name: "Message" }, {
9153
9682
  onClick: handleMessageClick
9154
9683
  }, [
9155
9684
  createVNode(unref(ElBadge), {
9156
- "is-dot": unref(unreadCount) > 0,
9685
+ "show-zero": false,
9686
+ value: __props.unreadCount,
9157
9687
  class: "message-badge"
9158
9688
  }, {
9159
9689
  default: withCtx(() => [
@@ -9164,12 +9694,12 @@ const _sfc_main$o = /* @__PURE__ */ Object.assign({ name: "Message" }, {
9164
9694
  }, null, 8, ["color"])
9165
9695
  ]),
9166
9696
  _: 1
9167
- }, 8, ["is-dot"])
9697
+ }, 8, ["value"])
9168
9698
  ]);
9169
9699
  };
9170
9700
  }
9171
9701
  });
9172
- const Message = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-fdaeb8e4"]]);
9702
+ const Message = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["__scopeId", "data-v-0a52aeb6"]]);
9173
9703
  const avatarImg = "data:image/gif;base64,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";
9174
9704
  const _hoisted_1$9 = { class: "flex items-center px-10px py-8px text-[var(--top-header-text-color)] hover:text-[var(--top-header-hover-color)] rounded-6px bg-[var(--top-header-company-bg-color)]" };
9175
9705
  const _hoisted_2$8 = { class: "pl-6px text-12px <lg:hidden truncate max-w-120px" };
@@ -10087,7 +10617,7 @@ const setI18nLanguage = (locale) => {
10087
10617
  const useLocale = () => {
10088
10618
  const changeLocale = async (locale) => {
10089
10619
  const globalI18n = i18n.global;
10090
- const langModule = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "../../locales/en.js": () => import("./en-BLMsUBCM.mjs"), "../../locales/zh-CN.js": () => import("./zh-CN-i4M-o5m6.mjs"), "../../locales/zh-TW.js": () => import("./zh-TW-DYC8NCr4.mjs") }), `../../locales/${locale}.js`);
10620
+ const langModule = await __variableDynamicImportRuntimeHelper(/* @__PURE__ */ Object.assign({ "../../locales/en.js": () => import("./en-DFjC_Whi.mjs"), "../../locales/zh-CN.js": () => import("./zh-CN-CYQhpMit.mjs"), "../../locales/zh-TW.js": () => import("./zh-TW-CWRW7QKU.mjs") }), `../../locales/${locale}.js`);
10091
10621
  globalI18n.setLocaleMessage(locale, langModule.default);
10092
10622
  setI18nLanguage(locale);
10093
10623
  };
@@ -10629,6 +11159,10 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
10629
11159
  onSwitchCompanyClick: {
10630
11160
  type: Function,
10631
11161
  default: null
11162
+ },
11163
+ unreadCount: {
11164
+ type: Number,
11165
+ default: 0
10632
11166
  }
10633
11167
  },
10634
11168
  setup(props, {
@@ -10666,6 +11200,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
10666
11200
  }, null) : void 0, message.value ? createVNode(Message, {
10667
11201
  "class": "custom-hover cursor-pointer",
10668
11202
  "color": iconColor.value,
11203
+ "unreadCount": props.unreadCount,
10669
11204
  "onMessageClick": props.onMessageClick
10670
11205
  }, null) : void 0, setting.value ? createVNode(Setting, {
10671
11206
  "class": "custom-hover cursor-pointer",
@@ -10690,7 +11225,7 @@ const _sfc_main$f = /* @__PURE__ */ defineComponent({
10690
11225
  };
10691
11226
  }
10692
11227
  });
10693
- const ToolHeader = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-caca6e2e"]]);
11228
+ const ToolHeader = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["__scopeId", "data-v-c5a11a5b"]]);
10694
11229
  const {
10695
11230
  getPrefixCls: getPrefixCls$1
10696
11231
  } = useDesign();
@@ -10701,7 +11236,11 @@ const useRenderLayout = (props, {
10701
11236
  onMessageClick,
10702
11237
  onLogoutClick,
10703
11238
  onClearCacheLogoutClick,
10704
- onSwitchCompanyClick
11239
+ onSwitchCompanyClick,
11240
+ onMenuFavoriteAdd,
11241
+ onMenuFavoriteCancel,
11242
+ onMenuRecentTrack,
11243
+ unreadCount
10705
11244
  }) => {
10706
11245
  const appStore = useAppStore();
10707
11246
  const permissionStore = usePermissionStore();
@@ -10745,13 +11284,17 @@ const useRenderLayout = (props, {
10745
11284
  "w-[var(--left-menu-min-width)]": collapse.value,
10746
11285
  "w-[var(--left-menu-max-width)]": !collapse.value
10747
11286
  }],
10748
- "onLogoClick": onLogoClick
11287
+ "onLogoClick": onLogoClick,
11288
+ "onMenuFavoriteAdd": onMenuFavoriteAdd,
11289
+ "onMenuFavoriteCancel": onMenuFavoriteCancel,
11290
+ "onMenuRecentTrack": onMenuRecentTrack
10749
11291
  }, null) : void 0, createVNode(ToolHeader, {
10750
11292
  "class": "flex-1",
10751
11293
  "onMessageClick": onMessageClick,
10752
11294
  "onLogoutClick": onLogoutClick,
10753
11295
  "onClearCacheLogoutClick": onClearCacheLogoutClick,
10754
- "onSwitchCompanyClick": onSwitchCompanyClick
11296
+ "onSwitchCompanyClick": onSwitchCompanyClick,
11297
+ "unreadCount": unreadCount
10755
11298
  }, null)]), createVNode("div", {
10756
11299
  "class": ["w-full flex", {
10757
11300
  "h-[calc(100%-var(--top-header-height))]": topNavNormal.value,
@@ -10763,6 +11306,9 @@ const useRenderLayout = (props, {
10763
11306
  "w-[var(--left-menu-max-width)]": !collapse.value
10764
11307
  }],
10765
11308
  "onLogoClick": onLogoClick,
11309
+ "onMenuFavoriteAdd": onMenuFavoriteAdd,
11310
+ "onMenuFavoriteCancel": onMenuFavoriteCancel,
11311
+ "onMenuRecentTrack": onMenuRecentTrack,
10766
11312
  "style": "transition: all var(--transition-time-02);"
10767
11313
  }, null) : void 0, createVNode(ToolHeader, {
10768
11314
  "class": "flex-1",
@@ -10805,7 +11351,10 @@ const useRenderLayout = (props, {
10805
11351
  }, festivalTopClass.value]
10806
11352
  }, [logo.value ? createVNode(_sfc_main$q, {
10807
11353
  "class": ["shrink-0 w-[var(--left-menu-max-width)]"],
10808
- "onLogoClick": onLogoClick
11354
+ "onLogoClick": onLogoClick,
11355
+ "onMenuFavoriteAdd": onMenuFavoriteAdd,
11356
+ "onMenuFavoriteCancel": onMenuFavoriteCancel,
11357
+ "onMenuRecentTrack": onMenuRecentTrack
10809
11358
  }, null) : void 0, tagsView.value && createVNode(TagsView, {
10810
11359
  "class": ["layout-border__bottom flex-1 min-w-0"]
10811
11360
  }, null), createVNode(ToolHeader, {
@@ -10813,7 +11362,8 @@ const useRenderLayout = (props, {
10813
11362
  "onMessageClick": onMessageClick,
10814
11363
  "onLogoutClick": onLogoutClick,
10815
11364
  "onClearCacheLogoutClick": onClearCacheLogoutClick,
10816
- "onSwitchCompanyClick": onSwitchCompanyClick
11365
+ "onSwitchCompanyClick": onSwitchCompanyClick,
11366
+ "unreadCount": unreadCount
10817
11367
  }, null)]), createVNode("div", {
10818
11368
  "class": [`${prefixCls$1}-content`, "w-full h-[calc(100%-var(--top-tool-height))]"]
10819
11369
  }, [props.scroll ? withDirectives(createVNode(ElScrollbar, {
@@ -10833,13 +11383,17 @@ const useRenderLayout = (props, {
10833
11383
  "w-[var(--left-menu-min-width)]": appStore.getCollapse,
10834
11384
  "w-[var(--left-menu-max-width)]": !appStore.getCollapse
10835
11385
  }],
10836
- "onLogoClick": onLogoClick
11386
+ "onLogoClick": onLogoClick,
11387
+ "onMenuFavoriteAdd": onMenuFavoriteAdd,
11388
+ "onMenuFavoriteCancel": onMenuFavoriteCancel,
11389
+ "onMenuRecentTrack": onMenuRecentTrack
10837
11390
  }, null) : void 0, createVNode(ToolHeader, {
10838
11391
  "class": "flex-1",
10839
11392
  "onMessageClick": onMessageClick,
10840
11393
  "onLogoutClick": onLogoutClick,
10841
11394
  "onClearCacheLogoutClick": onClearCacheLogoutClick,
10842
- "onSwitchCompanyClick": onSwitchCompanyClick
11395
+ "onSwitchCompanyClick": onSwitchCompanyClick,
11396
+ "unreadCount": unreadCount
10843
11397
  }, {
10844
11398
  default: () => createVNode(Menu, {
10845
11399
  "mode": "horizontal",
@@ -10891,7 +11445,10 @@ const renderLayout = (layout, props, {
10891
11445
  handleMessageClick,
10892
11446
  handleLogoutClick,
10893
11447
  handleClearCacheLogoutClick,
10894
- handleSwitchCompanyClick
11448
+ handleSwitchCompanyClick,
11449
+ handleMenuFavoriteAdd,
11450
+ handleMenuFavoriteCancel,
11451
+ handleMenuRecentTrack
10895
11452
  }) => {
10896
11453
  const {
10897
11454
  renderLeft,
@@ -10903,7 +11460,11 @@ const renderLayout = (layout, props, {
10903
11460
  onMessageClick: handleMessageClick,
10904
11461
  onLogoutClick: handleLogoutClick,
10905
11462
  onClearCacheLogoutClick: handleClearCacheLogoutClick,
10906
- onSwitchCompanyClick: handleSwitchCompanyClick
11463
+ onSwitchCompanyClick: handleSwitchCompanyClick,
11464
+ onMenuFavoriteAdd: handleMenuFavoriteAdd,
11465
+ onMenuFavoriteCancel: handleMenuFavoriteCancel,
11466
+ onMenuRecentTrack: handleMenuRecentTrack,
11467
+ unreadCount: props.unreadCount
10907
11468
  });
10908
11469
  layoutScrollRef.value = scrollRef2.value;
10909
11470
  switch (unref(layout)) {
@@ -10921,9 +11482,23 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
10921
11482
  scroll: {
10922
11483
  type: Boolean,
10923
11484
  default: true
11485
+ },
11486
+ unreadCount: {
11487
+ type: Number,
11488
+ default: 0
10924
11489
  }
10925
11490
  },
10926
- emits: ["logo-click", "message-click", "logout-click", "clear-cache-logout-click", "switch-company-click"],
11491
+ emits: [
11492
+ "logo-click",
11493
+ "message-click",
11494
+ "logout-click",
11495
+ "clear-cache-logout-click",
11496
+ "switch-company-click",
11497
+ // 菜单收藏相关事件(宿主监听后调接口,同步 store)
11498
+ "menu-favorite-add",
11499
+ "menu-favorite-cancel",
11500
+ "menu-recent-track"
11501
+ ],
10927
11502
  setup(props, {
10928
11503
  emit
10929
11504
  }) {
@@ -10946,6 +11521,15 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
10946
11521
  const handleSwitchCompanyClick = (company) => {
10947
11522
  emit("switch-company-click", company);
10948
11523
  };
11524
+ const handleMenuFavoriteAdd = (record) => {
11525
+ emit("menu-favorite-add", record);
11526
+ };
11527
+ const handleMenuFavoriteCancel = (menuId) => {
11528
+ emit("menu-favorite-cancel", menuId);
11529
+ };
11530
+ const handleMenuRecentTrack = (record) => {
11531
+ emit("menu-recent-track", record);
11532
+ };
10949
11533
  return () => createVNode("section", {
10950
11534
  "class": [prefixCls, `${prefixCls}__${layout.value}`, "w-[100%] h-[100%] relative", `${prefixCls}__${theme.value}`]
10951
11535
  }, [renderLayout(layout, props, {
@@ -10953,11 +11537,14 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
10953
11537
  handleMessageClick,
10954
11538
  handleLogoutClick,
10955
11539
  handleClearCacheLogoutClick,
10956
- handleSwitchCompanyClick
11540
+ handleSwitchCompanyClick,
11541
+ handleMenuFavoriteAdd,
11542
+ handleMenuFavoriteCancel,
11543
+ handleMenuRecentTrack
10957
11544
  }), props.scroll && createVNode(_sfc_main$y, null, null)]);
10958
11545
  }
10959
11546
  });
10960
- const Layout = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-0945fd78"]]);
11547
+ const Layout = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-8a9b45c4"]]);
10961
11548
  const _sfc_main$d = {
10962
11549
  __name: "ConfigGlobal",
10963
11550
  props: {
@@ -13133,6 +13720,8 @@ export {
13133
13720
  UploadImgs as BmpUploadImgs,
13134
13721
  useAppStore as BmpUseAppStore,
13135
13722
  useAppStoreWithOut as BmpUseAppStoreWithOut,
13723
+ useFavoriteStore as BmpUseFavoriteStore,
13724
+ useFavoriteStoreWithOut as BmpUseFavoriteStoreWithOut,
13136
13725
  useLayout as BmpUseLayout,
13137
13726
  useLocaleStore as BmpUseLocaleStore,
13138
13727
  useLocaleStoreWithOut as BmpUseLocaleStoreWithOut,