@pubinfo/core 2.0.0 → 2.0.2

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.
Files changed (42) hide show
  1. package/dist/{AppSetting-DqVYDIHj.js → AppSetting-C-uQWp09.js} +15 -15
  2. package/dist/{HCheckList.vue_vue_type_script_setup_true_lang-SrNklW3P.js → HCheckList.vue_vue_type_script_setup_true_lang-Dix75g7Y.js} +1 -1
  3. package/dist/{HToggle-DGTP9jYA.js → HToggle-CkLtDSqB.js} +1 -1
  4. package/dist/{PreferencesContent-5NtwK9RQ.js → PreferencesContent-uLLIbpgi.js} +4 -4
  5. package/dist/{SettingBreadcrumb-BudqQsuJ.js → SettingBreadcrumb-eOf8TqIs.js} +3 -3
  6. package/dist/{SettingCopyright-VUberG4R.js → SettingCopyright-DwaL1fDm.js} +2 -2
  7. package/dist/{SettingEnableTransition-C6NYf021.js → SettingEnableTransition-CBybF9vH.js} +2 -2
  8. package/dist/{SettingHome-BTaeKgwN.js → SettingHome-DZjnXioZ.js} +2 -2
  9. package/dist/{SettingMenu-D9Aon2LP.js → SettingMenu-BoDFUNC2.js} +3 -3
  10. package/dist/{SettingMode-DaqVd9Mq.js → SettingMode-BjC403k0.js} +1 -1
  11. package/dist/{SettingNavSearch-N4JIheIk.js → SettingNavSearch-l7X-Iwjk.js} +2 -2
  12. package/dist/{SettingOther-tLulcors.js → SettingOther-C07luGm-.js} +2 -2
  13. package/dist/{SettingPage-CEjWB45R.js → SettingPage-CpCp1Tnk.js} +2 -2
  14. package/dist/{SettingTabbar-DyeLhcCT.js → SettingTabbar-BpvyU_8s.js} +3 -3
  15. package/dist/{SettingThemes-C2M3tsVl.js → SettingThemes-BNqblNbu.js} +1 -1
  16. package/dist/{SettingToolbar-DI7de6i0.js → SettingToolbar-C-s6o0qU.js} +2 -2
  17. package/dist/{SettingTopbar-BgIoXeAq.js → SettingTopbar-DlASsEm4.js} +3 -3
  18. package/dist/{SettingWidthMode-DIAU4s5e.js → SettingWidthMode-DUhpdqt0.js} +1 -1
  19. package/dist/{TopThinMode-JNUHrJI2.js → TopThinMode-C4ENwLBo.js} +1 -1
  20. package/dist/{colors-DxWfHM_v.js → colors-DEL1DLxl.js} +1 -1
  21. package/dist/features/stores/modules/user.d.ts +2 -2
  22. package/dist/{index-D4v4g8FJ.js → index-BAQ3G_yS.js} +26 -26
  23. package/dist/{index-BFRIv97x.js → index-BC4fIMeo.js} +2 -2
  24. package/dist/{index-BH-vHGvk.js → index-C5-BAU1l.js} +1 -1
  25. package/dist/{index-5fRpGyLW.js → index-Cl9ha8wq.js} +4 -4
  26. package/dist/{index-CNVn3Ubv.js → index-CqRJBmZ2.js} +2 -2
  27. package/dist/{index-Cf-u1Zqh.js → index-DhzrIShp.js} +1 -1
  28. package/dist/{index-Dv7UUFkD.js → index-Dm0Yz_my.js} +972 -968
  29. package/dist/{index-DQGnbEGS.js → index-DoyP74bp.js} +2 -2
  30. package/dist/{index-C7xIGcDc.js → index-RctfGvXs.js} +6 -6
  31. package/dist/index.js +1 -1
  32. package/dist/{pick-VFuUwFn-.js → pick-BvpiopvO.js} +1 -1
  33. package/dist/style.css +1 -1
  34. package/package.json +5 -5
  35. package/src/built-in/authentication/pages/change-password/components/ChangePasswordForm/index.vue +1 -1
  36. package/src/built-in/layout-component/components/Header/TopMode/index.vue +2 -2
  37. package/src/built-in/layout-component/components/Menu/item.vue +6 -6
  38. package/src/built-in/layout-component/components/Topbar/Tabbar/MoreAction.vue +42 -24
  39. package/src/built-in/layout-component/components/Topbar/Tabbar/index.vue +43 -25
  40. package/src/features/stores/modules/user.ts +3 -3
  41. package/types/menu.d.ts +1 -1
  42. package/types/user.d.ts +3 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pubinfo/core",
3
3
  "type": "module",
4
- "version": "2.0.0",
4
+ "version": "2.0.2",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -26,8 +26,8 @@
26
26
  "pinia": "^3.0.3",
27
27
  "vue": "^3.5.17",
28
28
  "vue-router": "^4.5.1",
29
- "@pubinfo/config": "2.0.0",
30
- "@pubinfo/vite": "2.0.0"
29
+ "@pubinfo/config": "2.0.2",
30
+ "@pubinfo/vite": "2.0.2"
31
31
  },
32
32
  "dependencies": {
33
33
  "@alova/adapter-axios": "^2.0.16",
@@ -85,8 +85,8 @@
85
85
  "vite-plugin-dts": "^4.5.4",
86
86
  "vue": "^3.5.17",
87
87
  "vue-router": "^4.5.1",
88
- "@pubinfo/config": "2.0.0",
89
- "@pubinfo/vite": "2.0.0"
88
+ "@pubinfo/config": "2.0.2",
89
+ "@pubinfo/vite": "2.0.2"
90
90
  },
91
91
  "scripts": {
92
92
  "dev": "vite build -w -m watch",
@@ -62,7 +62,7 @@ const rules: Record<string, Rule[]> = {
62
62
  async function submit() {
63
63
  try {
64
64
  await changePasswordForm.value?.validate();
65
- await userStore.changeUserPassword({
65
+ await userStore.changePassword({
66
66
  oldPassword: formState.password,
67
67
  newPassword: formState.newPassword,
68
68
  token: props.token,
@@ -120,10 +120,10 @@ onMounted(() => {
120
120
  <template v-if="iconName(index === menuStore.actived, item.meta?.icon, item.meta?.activeIcon)">
121
121
  <!-- 当存在 iconOptions 且 boxType 不为 'null' 时,展示带边框/渐变的盒子效果 -->
122
122
  <PubinfoIcon
123
- v-if="item.meta?.iconOptions"
123
+ v-if="item.meta?.iconOptions?.boxType && item.meta.iconOptions.boxType !== 'null'"
124
124
  :name="iconName(index === menuStore.actived, item.meta?.icon, item.meta?.activeIcon)!"
125
125
  small
126
- :box="(item.meta.iconOptions.boxType as any) || 'prism'"
126
+ :box="item.meta.iconOptions.boxType as any"
127
127
  :size="18"
128
128
  :angle="item.meta.iconOptions.angle"
129
129
  :background="item.meta.iconOptions.background"
@@ -57,10 +57,10 @@ const iconOptions = computed(() => ((props.item.meta as any)?.iconOptions) as un
57
57
  iconColor?: string
58
58
  });
59
59
 
60
- // 统一盒子类型:存在 iconOptions 时启用盒子,未指定或为 'null' 时默认 prism
61
- const computedBoxType = computed(() => {
62
- const bt = iconOptions.value?.boxType as any;
63
- return bt && bt !== 'null' ? bt : 'prism';
60
+ // 统一盒子类型:仅当显式为 square/prism 时启用盒子
61
+ const computedBoxType = computed<'square' | 'prism' | undefined>(() => {
62
+ const bt = iconOptions.value?.boxType;
63
+ return bt && bt !== 'null' ? bt : undefined;
64
64
  });
65
65
 
66
66
  // 统一安全的图标颜色(仅 AntD 图标使用);无配置则为 undefined
@@ -112,10 +112,10 @@ defineExpose({
112
112
  <template v-if="icon && icon !== 'system-point'">
113
113
  <!-- 有 iconOptions 时启用带边框/渐变的盒子效果 -->
114
114
  <PubinfoIcon
115
- v-if="iconOptions"
115
+ v-if="iconOptions && computedBoxType"
116
116
  small
117
117
  :name="icon"
118
- :box="computedBoxType as any"
118
+ :box="computedBoxType!"
119
119
  :size="20"
120
120
  :angle="iconOptions?.angle"
121
121
  :background="iconOptions?.background"
@@ -91,14 +91,7 @@ function stripPath(fullPath: string) {
91
91
  return fullPath.split(/[?#]/)[0];
92
92
  }
93
93
 
94
- // 查找与 tab 对应的路由记录
95
- function findRouteRecordByElement(element: Tabbar.recordRaw) {
96
- const pathOnly = stripPath(element.fullPath);
97
- const all = [...routeStore.flatSystemRoutes, ...routeStore.flatRoutes] as any[];
98
- return all.find(r => r.path === pathOnly);
99
- }
100
-
101
- // 解析该 tab 的 iconOptions(优先当前路由,其次面包屑链路上最近的一个)
94
+ // 解析该 tab 的 iconOptions(优先使用实际匹配的路由记录,兼容动态路由)
102
95
  function resolveIconOptions(element: Tabbar.recordRaw): undefined | {
103
96
  boxType?: 'square' | 'prism' | 'null'
104
97
  angle?: number | string
@@ -106,22 +99,47 @@ function resolveIconOptions(element: Tabbar.recordRaw): undefined | {
106
99
  radius?: number | string
107
100
  iconColor?: string
108
101
  } {
109
- const r: any = findRouteRecordByElement(element);
110
- let options = (r?.meta as any)?.iconOptions;
111
- if (!options && r?.meta?.breadcrumbNeste?.length) {
112
- const found = [...r.meta.breadcrumbNeste].reverse().find((it: any) => it?.iconOptions);
102
+ const resolved = router.resolve(element.fullPath);
103
+ const matched = [...(resolved.matched as any[])].reverse();
104
+ const matchedRecordWithIcon = matched.find(record => (record?.meta as any)?.iconOptions);
105
+ if (matchedRecordWithIcon?.meta?.iconOptions) {
106
+ return matchedRecordWithIcon.meta.iconOptions as any;
107
+ }
108
+
109
+ const pathOnly = stripPath(element.fullPath);
110
+ const all = [...routeStore.flatSystemRoutes, ...routeStore.flatRoutes] as any[];
111
+ let record = element.routeName
112
+ ? all.find(r => r.name === element.routeName)
113
+ : undefined;
114
+
115
+ if (!record) {
116
+ record = all.find(r => r.path === pathOnly);
117
+ }
118
+
119
+ let options = (record?.meta as any)?.iconOptions;
120
+ if (!options && record?.meta?.breadcrumbNeste?.length) {
121
+ const found = [...record.meta.breadcrumbNeste].reverse().find((it: any) => it?.iconOptions);
113
122
  options = found?.iconOptions;
114
123
  }
115
124
  return options;
116
125
  }
117
126
 
118
- function computeBoxType(options: ReturnType<typeof resolveIconOptions>) {
119
- const bt = (options as any)?.boxType as any;
120
- return bt && bt !== 'null' ? bt : 'prism';
127
+ type ResolvedIconOptions = ReturnType<typeof resolveIconOptions>;
128
+
129
+ const dropdownIconOptions = computed<Record<string, ResolvedIconOptions>>(() => {
130
+ return tabbarStore.list.reduce<Record<string, ResolvedIconOptions>>((acc, element) => {
131
+ acc[element.tabId] = resolveIconOptions(element);
132
+ return acc;
133
+ }, {} as Record<string, ResolvedIconOptions>);
134
+ });
135
+
136
+ function computeBoxType(options: ResolvedIconOptions): 'square' | 'prism' | undefined {
137
+ const bt = options?.boxType;
138
+ return bt && bt !== 'null' ? bt : undefined;
121
139
  }
122
140
 
123
- function getSafeIconColor(options: ReturnType<typeof resolveIconOptions>): string | undefined {
124
- return (options as any)?.iconColor || undefined;
141
+ function getSafeIconColor(options: ResolvedIconOptions): string | undefined {
142
+ return options?.iconColor || undefined;
125
143
  }
126
144
  </script>
127
145
 
@@ -165,21 +183,21 @@ function getSafeIconColor(options: ReturnType<typeof resolveIconOptions>): strin
165
183
  <div :key="element.tabId" class="title" :title="element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title)" @click="router.push(element.fullPath)">
166
184
  <template v-if="settingsStore.settings.tabbar.enableIcon && iconName(element.tabId === activedTabId, element.icon, element.activeIcon)">
167
185
  <PubinfoIcon
168
- v-if="resolveIconOptions(element)"
186
+ v-if="computeBoxType(dropdownIconOptions[element.tabId])"
169
187
  small
170
188
  :name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!"
171
- :box="computeBoxType(resolveIconOptions(element)) as any"
189
+ :box="(computeBoxType(dropdownIconOptions[element.tabId]) as 'square' | 'prism')"
172
190
  :size="16"
173
- :angle="resolveIconOptions(element)?.angle"
174
- :background="resolveIconOptions(element)?.background"
175
- :radius="resolveIconOptions(element)?.radius"
176
- :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? (getSafeIconColor(resolveIconOptions(element)) || '#ffffff') : undefined"
191
+ :angle="dropdownIconOptions[element.tabId]?.angle"
192
+ :background="dropdownIconOptions[element.tabId]?.background"
193
+ :radius="dropdownIconOptions[element.tabId]?.radius"
194
+ :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? (getSafeIconColor(dropdownIconOptions[element.tabId]) || '#ffffff') : undefined"
177
195
  />
178
196
  <PubinfoIcon
179
197
  v-else
180
198
  :name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!"
181
199
  :size="16"
182
- :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? getSafeIconColor(resolveIconOptions(element)) : undefined"
200
+ :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? getSafeIconColor(dropdownIconOptions[element.tabId]) : undefined"
183
201
  />
184
202
  </template>
185
203
  {{ element.customTitleList.find(item => item.fullPath === element.fullPath)?.title || generateTitle(element.title) }}
@@ -246,14 +246,7 @@ function stripPath(fullPath: string) {
246
246
  return fullPath.split(/[?#]/)[0];
247
247
  }
248
248
 
249
- // 查找与 tab 对应的路由记录
250
- function findRouteRecordByElement(element: Tabbar.recordRaw) {
251
- const pathOnly = stripPath(element.fullPath);
252
- const all = [...routeStore.flatSystemRoutes, ...routeStore.flatRoutes] as any[];
253
- return all.find(r => r.path === pathOnly);
254
- }
255
-
256
- // 解析该 tab 的 iconOptions(优先当前路由,其次面包屑链路上最近的一个)
249
+ // 解析该 tab 的 iconOptions(优先使用实际匹配的路由记录,兼容动态路由)
257
250
  function resolveIconOptions(element: Tabbar.recordRaw): undefined | {
258
251
  boxType?: 'square' | 'prism' | 'null'
259
252
  angle?: number | string
@@ -261,24 +254,49 @@ function resolveIconOptions(element: Tabbar.recordRaw): undefined | {
261
254
  radius?: number | string
262
255
  iconColor?: string
263
256
  } {
264
- const r: any = findRouteRecordByElement(element);
265
- let options = (r?.meta as any)?.iconOptions;
266
- if (!options && r?.meta?.breadcrumbNeste?.length) {
267
- const found = [...r.meta.breadcrumbNeste].reverse().find((it: any) => it?.iconOptions);
257
+ const resolved = router.resolve(element.fullPath);
258
+ const matched = [...(resolved.matched as any[])].reverse();
259
+ const matchedRecordWithIcon = matched.find(record => (record?.meta as any)?.iconOptions);
260
+ if (matchedRecordWithIcon?.meta?.iconOptions) {
261
+ return matchedRecordWithIcon.meta.iconOptions as any;
262
+ }
263
+
264
+ const pathOnly = stripPath(element.fullPath);
265
+ const all = [...routeStore.flatSystemRoutes, ...routeStore.flatRoutes] as any[];
266
+ let record = element.routeName
267
+ ? all.find(r => r.name === element.routeName)
268
+ : undefined;
269
+
270
+ if (!record) {
271
+ record = all.find(r => r.path === pathOnly);
272
+ }
273
+
274
+ let options = (record?.meta as any)?.iconOptions;
275
+ if (!options && record?.meta?.breadcrumbNeste?.length) {
276
+ const found = [...record.meta.breadcrumbNeste].reverse().find((it: any) => it?.iconOptions);
268
277
  options = found?.iconOptions;
269
278
  }
270
279
  return options;
271
280
  }
272
281
 
273
- // 统一盒子类型:存在 iconOptions 时启用盒子;未指定或为 'null' 时默认 prism
274
- function computeBoxType(options: ReturnType<typeof resolveIconOptions>) {
275
- const bt = (options as any)?.boxType as any;
276
- return bt && bt !== 'null' ? bt : 'prism';
282
+ type ResolvedIconOptions = ReturnType<typeof resolveIconOptions>;
283
+
284
+ const tabIconOptions = computed<Record<string, ResolvedIconOptions>>(() => {
285
+ return tabbarStore.list.reduce<Record<string, ResolvedIconOptions>>((acc, element) => {
286
+ acc[element.tabId] = resolveIconOptions(element);
287
+ return acc;
288
+ }, {} as Record<string, ResolvedIconOptions>);
289
+ });
290
+
291
+ // 统一盒子类型:仅在显式指定为 square/prism 时启用盒子
292
+ function computeBoxType(options: ResolvedIconOptions): 'square' | 'prism' | undefined {
293
+ const bt = options?.boxType;
294
+ return bt && bt !== 'null' ? bt : undefined;
277
295
  }
278
296
 
279
297
  // 仅 AntD 图标使用安全颜色;无配置则为 undefined
280
- function getSafeIconColor(options: ReturnType<typeof resolveIconOptions>): string | undefined {
281
- return (options as any)?.iconColor || undefined;
298
+ function getSafeIconColor(options: ResolvedIconOptions): string | undefined {
299
+ return options?.iconColor || undefined;
282
300
  }
283
301
 
284
302
  onMounted(() => {
@@ -368,15 +386,15 @@ onUnmounted(() => {
368
386
  <template v-if="settingsStore.settings.tabbar.enableIcon && iconName(element.tabId === activedTabId, element.icon, element.activeIcon)">
369
387
  <!-- 有 iconOptions 时启用带边框/渐变的盒子效果,与 Menu 保持一致 -->
370
388
  <PubinfoIcon
371
- v-if="resolveIconOptions(element)"
389
+ v-if="computeBoxType(tabIconOptions[element.tabId])"
372
390
  small
373
391
  :name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!"
374
- :box="computeBoxType(resolveIconOptions(element)) as any"
392
+ :box="(computeBoxType(tabIconOptions[element.tabId]) as 'square' | 'prism')"
375
393
  :size="16"
376
- :angle="resolveIconOptions(element)?.angle"
377
- :background="resolveIconOptions(element)?.background"
378
- :radius="resolveIconOptions(element)?.radius"
379
- :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? (getSafeIconColor(resolveIconOptions(element)) || '#ffffff') : undefined"
394
+ :angle="tabIconOptions[element.tabId]?.angle"
395
+ :background="tabIconOptions[element.tabId]?.background"
396
+ :radius="tabIconOptions[element.tabId]?.radius"
397
+ :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? (getSafeIconColor(tabIconOptions[element.tabId]) || '#ffffff') : undefined"
380
398
  class="icon"
381
399
  />
382
400
  <!-- 无 iconOptions 时保持原样(纯图标),但若提供图标色也生效 -->
@@ -384,7 +402,7 @@ onUnmounted(() => {
384
402
  v-else
385
403
  :name="iconName(element.tabId === activedTabId, element.icon, element.activeIcon)!"
386
404
  :size="16"
387
- :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? getSafeIconColor(resolveIconOptions(element)) : undefined"
405
+ :color="(iconName(element.tabId === activedTabId, element.icon, element.activeIcon) || '').startsWith('antd:') ? getSafeIconColor(tabIconOptions[element.tabId]) : undefined"
388
406
  class="icon"
389
407
  />
390
408
  </template>
@@ -37,7 +37,7 @@ export interface UserStore {
37
37
  logout: () => void
38
38
 
39
39
  /** 修改密码 */
40
- changeUserPassword: (form: API.putRbacUserChangePasswordParams & {
40
+ changePassword: (form: API.putRbacUserChangePasswordParams & {
41
41
  token?: string | string[]
42
42
  }) => Promise<API.ResponseDataVoid>
43
43
 
@@ -174,7 +174,7 @@ const useUserStore = defineStore<STORE_NAME.USER, UserStore>(
174
174
  * @param form - 包含要修改的密码和令牌的表单数据
175
175
  * @returns 修改密码的结果
176
176
  */
177
- async function changeUserPassword(form: API.putRbacUserChangePasswordParams & { token?: string | string[] }) {
177
+ async function changePassword(form: API.putRbacUserChangePasswordParams & { token?: string | string[] }) {
178
178
  const headers = {} as AxiosRequestHeaders;
179
179
  if (form.token) {
180
180
  headers.authorization = form.token;
@@ -232,7 +232,7 @@ const useUserStore = defineStore<STORE_NAME.USER, UserStore>(
232
232
  getPermissions,
233
233
  login,
234
234
  logout,
235
- changeUserPassword,
235
+ changePassword,
236
236
  changeOrg,
237
237
  setToken,
238
238
  clean,
package/types/menu.d.ts CHANGED
@@ -30,7 +30,7 @@ export declare namespace Menu {
30
30
  from: string
31
31
  to: string
32
32
  }
33
- boxType?: 'square' | 'prism'
33
+ boxType?: 'square' | 'prism' | 'null'
34
34
  iconColor?: string
35
35
  radius?: number | string
36
36
  }
package/types/user.d.ts CHANGED
@@ -29,9 +29,9 @@ declare interface User {
29
29
  */
30
30
  token: string
31
31
 
32
- /*
33
- * 刷新token
34
- */
32
+ /**
33
+ * 刷新token
34
+ */
35
35
  refreshToken: string
36
36
 
37
37
  /**