Browse Source

refactor(project): simplified part of the package, code optimization

pull/3993/head
vben 2 years ago
parent
commit
daa31f7156
  1. 2
      apps/backend-mock/src/modules/menu/menu.controller.ts
  2. 12
      apps/web-antd/src/forward/access.ts
  3. 4
      apps/web-antd/src/locales/langs/en-US.json
  4. 4
      apps/web-antd/src/locales/langs/zh-CN.json
  5. 2
      apps/web-antd/src/router/routes/modules/demos.ts
  6. 4
      apps/web-antd/src/views/dashboard/analytics/index.vue
  7. 45
      apps/web-antd/src/views/demos/access/button-control.vue
  8. 8
      apps/web-antd/src/views/demos/access/index.vue
  9. 2
      apps/web-antd/src/views/demos/features/login-expired/index.vue
  10. 6
      package.json
  11. 1
      packages/@core/forward/helpers/package.json
  12. 0
      packages/@core/forward/helpers/src/generate-menus.test.ts
  13. 2
      packages/@core/forward/helpers/src/generate-menus.ts
  14. 20
      packages/@core/forward/helpers/src/generate-routes-backend.ts
  15. 0
      packages/@core/forward/helpers/src/generate-routes-frontend.test.ts
  16. 1
      packages/@core/forward/helpers/src/generate-routes-frontend.ts
  17. 3
      packages/@core/forward/helpers/src/index.ts
  18. 2
      packages/@core/forward/preferences/package.json
  19. 7
      packages/@core/forward/preferences/src/constants.ts
  20. 11
      packages/@core/forward/preferences/src/preferences.test.ts
  21. 9
      packages/@core/forward/preferences/src/preferences.ts
  22. 33
      packages/@core/forward/preferences/src/types.ts
  23. 7
      packages/@core/shared/cache/build.config.ts
  24. 40
      packages/@core/shared/cache/package.json
  25. 6
      packages/@core/shared/cache/tsconfig.json
  26. 7
      packages/@core/shared/colorful/build.config.ts
  27. 42
      packages/@core/shared/colorful/package.json
  28. 6
      packages/@core/shared/colorful/tsconfig.json
  29. 3
      packages/@core/shared/design-tokens/README.md
  30. 39
      packages/@core/shared/design-tokens/package.json
  31. 6
      packages/@core/shared/design-tokens/tsconfig.json
  32. 3
      packages/@core/shared/design-tokens/vite.config.mts
  33. 0
      packages/@core/shared/design/src/design-tokens/dark/index.css
  34. 0
      packages/@core/shared/design/src/design-tokens/default/index.css
  35. 0
      packages/@core/shared/design/src/design-tokens/index.ts
  36. 1
      packages/@core/shared/design/src/index.ts
  37. 2
      packages/@core/shared/toolkit/package.json
  38. 0
      packages/@core/shared/toolkit/src/cache/index.ts
  39. 0
      packages/@core/shared/toolkit/src/cache/storage-manager.test.ts
  40. 0
      packages/@core/shared/toolkit/src/cache/storage-manager.ts
  41. 0
      packages/@core/shared/toolkit/src/cache/types.ts
  42. 2
      packages/@core/shared/toolkit/src/colorful/convert.test.ts
  43. 0
      packages/@core/shared/toolkit/src/colorful/convert.ts
  44. 2
      packages/@core/shared/toolkit/src/colorful/generator.ts
  45. 2
      packages/@core/shared/toolkit/src/colorful/index.ts
  46. 2
      packages/@core/shared/toolkit/src/index.ts
  47. 22
      packages/@core/shared/typings/src/app.d.ts
  48. 33
      packages/@core/shared/typings/src/basic.d.ts
  49. 1
      packages/@core/shared/typings/src/index.ts
  50. 29
      packages/@core/shared/typings/src/vue-router.d.ts
  51. 1
      packages/@core/ui-kit/shadcn-ui/package.json
  52. 2
      packages/@core/ui-kit/shadcn-ui/src/components/menu-badge/menu-badge.vue
  53. 9
      packages/business/access/package.json
  54. 43
      packages/business/access/src/access-control.vue
  55. 29
      packages/business/access/src/code-access.vue
  56. 45
      packages/business/access/src/generate-accessible.ts
  57. 6
      packages/business/access/src/index.ts
  58. 29
      packages/business/access/src/role-access.vue
  59. 17
      packages/business/access/src/types.ts
  60. 3
      packages/business/access/tsconfig.json
  61. 6
      packages/business/layouts/package.json
  62. 29
      packages/business/layouts/src/basic/tabbar/use-tabs.ts
  63. 2
      packages/business/layouts/src/widgets/breadcrumb.vue
  64. 2
      packages/business/layouts/src/widgets/color-toggle.vue
  65. 2
      packages/business/layouts/src/widgets/global-search/global-search.vue
  66. 2
      packages/business/layouts/src/widgets/global-search/search-panel.vue
  67. 2
      packages/business/layouts/src/widgets/language-toggle.vue
  68. 2
      packages/business/layouts/src/widgets/layout-toggle.vue
  69. 4
      packages/business/layouts/src/widgets/preferences/blocks/general/general.vue
  70. 4
      packages/business/layouts/src/widgets/preferences/blocks/input-item.vue
  71. 4
      packages/business/layouts/src/widgets/preferences/blocks/layout/breadcrumb.vue
  72. 4
      packages/business/layouts/src/widgets/preferences/blocks/layout/header.vue
  73. 2
      packages/business/layouts/src/widgets/preferences/blocks/layout/layout.vue
  74. 4
      packages/business/layouts/src/widgets/preferences/blocks/layout/navigation.vue
  75. 4
      packages/business/layouts/src/widgets/preferences/blocks/number-field-item.vue
  76. 4
      packages/business/layouts/src/widgets/preferences/blocks/select-item.vue
  77. 4
      packages/business/layouts/src/widgets/preferences/blocks/theme/builtin.vue
  78. 2
      packages/business/layouts/src/widgets/preferences/blocks/theme/theme.vue
  79. 4
      packages/business/layouts/src/widgets/preferences/blocks/toggle-item.vue
  80. 10
      packages/business/layouts/src/widgets/preferences/preferences-sheet.vue
  81. 9
      packages/business/layouts/src/widgets/preferences/preferences.vue
  82. 3
      packages/business/layouts/src/widgets/theme-toggle/theme-toggle.vue
  83. 2
      packages/business/layouts/src/widgets/user-dropdown/user-dropdown.vue
  84. 4
      packages/business/universal-ui/src/dashboard/analysis/analysis-charts-tabs.vue
  85. 7
      packages/styles/package.json
  86. 1
      packages/styles/src/index.ts
  87. 2
      packages/types/src/index.ts
  88. 13
      packages/types/src/router.ts
  89. 11
      packages/types/src/ui.d.ts
  90. 25
      packages/types/src/user.d.ts
  91. 61
      pnpm-lock.yaml
  92. 12
      vben-admin.code-workspace

2
apps/backend-mock/src/modules/menu/menu.controller.ts

@ -96,7 +96,7 @@ export class MenuController {
path: 'access', path: 'access',
meta: { meta: {
icon: 'mdi:cloud-key-outline', icon: 'mdi:cloud-key-outline',
title: 'page.demos.access.backendControl', title: 'page.demos.access.backendPermissions',
}, },
redirect: '/demos/access/page-control', redirect: '/demos/access/page-control',
children: [ children: [

12
apps/web-antd/src/forward/access.ts

@ -1,7 +1,9 @@
import type { GeneratorMenuAndRoutesOptions } from '@vben/access'; import type {
import type { ComponentRecordType } from '@vben/types'; ComponentRecordType,
GenerateMenuAndRoutesOptions,
} from '@vben/types';
import { generateMenusAndRoutes } from '@vben/access'; import { generateAccessible } from '@vben/access';
import { preferences } from '@vben-core/preferences'; import { preferences } from '@vben-core/preferences';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
@ -13,7 +15,7 @@ import { $t } from '#/locales';
const forbiddenComponent = () => const forbiddenComponent = () =>
import('#/views/_essential/fallback/forbidden.vue'); import('#/views/_essential/fallback/forbidden.vue');
async function generateAccess(options: GeneratorMenuAndRoutesOptions) { async function generateAccess(options: GenerateMenuAndRoutesOptions) {
const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
const layoutMap: ComponentRecordType = { const layoutMap: ComponentRecordType = {
@ -21,7 +23,7 @@ async function generateAccess(options: GeneratorMenuAndRoutesOptions) {
IFrameView, IFrameView,
}; };
return await generateMenusAndRoutes(preferences.app.accessMode, { return await generateAccessible(preferences.app.accessMode, {
...options, ...options,
fetchMenuListAsync: async () => { fetchMenuListAsync: async () => {
message.loading({ message.loading({

4
apps/web-antd/src/locales/langs/en-US.json

@ -3,8 +3,8 @@
"demos": { "demos": {
"title": "Demos", "title": "Demos",
"access": { "access": {
"frontendControl": "Frontend Control", "frontendPermissions": "Frontend Permissions",
"backendControl": "Backend Control", "backendPermissions": "Backend Permissions",
"pageAccess": "Page Access", "pageAccess": "Page Access",
"buttonControl": "Button Control", "buttonControl": "Button Control",
"menuVisible403": "Menu Visible(403)", "menuVisible403": "Menu Visible(403)",

4
apps/web-antd/src/locales/langs/zh-CN.json

@ -3,8 +3,8 @@
"demos": { "demos": {
"title": "演示", "title": "演示",
"access": { "access": {
"frontendControl": "前端控制", "frontendPermissions": "前端权限",
"backendControl": "后端控制", "backendPermissions": "后端权限",
"pageAccess": "页面访问", "pageAccess": "页面访问",
"buttonControl": "按钮控制", "buttonControl": "按钮控制",
"menuVisible403": "菜单可见(403)", "menuVisible403": "菜单可见(403)",

2
apps/web-antd/src/router/routes/modules/demos.ts

@ -19,7 +19,7 @@ const routes: RouteRecordRaw[] = [
{ {
meta: { meta: {
icon: 'mdi:shield-key-outline', icon: 'mdi:shield-key-outline',
title: $t('page.demos.access.frontendControl'), title: $t('page.demos.access.frontendPermissions'),
}, },
name: 'Access', name: 'Access',
path: 'access', path: 'access',

4
apps/web-antd/src/views/dashboard/analytics/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { TabsItem } from '@vben/types'; import type { TabsOption } from '@vben/types';
import type { AnalysisOverviewItem } from '@vben/universal-ui'; import type { AnalysisOverviewItem } from '@vben/universal-ui';
import { import {
@ -53,7 +53,7 @@ const overviewItems: AnalysisOverviewItem[] = [
}, },
]; ];
const chartTabs: TabsItem[] = [ const chartTabs: TabsOption[] = [
{ {
label: '流量趋势', label: '流量趋势',
value: 'trends', value: 'trends',

45
apps/web-antd/src/views/demos/access/button-control.vue

@ -3,7 +3,7 @@ import type { LoginAndRegisterParams } from '@vben/universal-ui';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { CodeAccess, useAccess } from '@vben/access'; import { AccessControl, useAccess } from '@vben/access';
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
@ -59,9 +59,9 @@ async function changeAccount(role: string) {
<div class="card-box mt-5 p-5 font-semibold"> <div class="card-box mt-5 p-5 font-semibold">
<div class="mb-3"> <div class="mb-3">
<span class="text-lg">当前账号:</span> <span class="text-lg">当前角色:</span>
<span class="text-primary mx-4"> <span class="text-primary mx-4 text-lg">
{{ accessStore.userRoles }} {{ accessStore.userRoles?.[0] }}
</span> </span>
</div> </div>
@ -82,21 +82,40 @@ async function changeAccount(role: string) {
</div> </div>
<div class="card-box mt-5 p-5 font-semibold"> <div class="card-box mt-5 p-5 font-semibold">
<div class="mb-3 text-lg">组件形式控制</div> <div class="mb-3 text-lg">组件形式控制 - 权限码方式</div>
<CodeAccess :value="['AC_100100']"> <AccessControl :value="['AC_100100']" type="code">
<Button class="mr-4"> Super 账号可见 ["AC_1000001"] </Button> <Button class="mr-4"> Super 账号可见 ["AC_1000001"] </Button>
</CodeAccess> </AccessControl>
<CodeAccess :value="['AC_100030']"> <AccessControl :value="['AC_100030']" type="code">
<Button class="mr-4"> Admin 账号可见 ["AC_100010"] </Button> <Button class="mr-4"> Admin 账号可见 ["AC_100010"] </Button>
</CodeAccess> </AccessControl>
<CodeAccess :value="['AC_1000001']"> <AccessControl :value="['AC_1000001']" type="code">
<Button class="mr-4"> User 账号可见 ["AC_1000001"] </Button> <Button class="mr-4"> User 账号可见 ["AC_1000001"] </Button>
</CodeAccess> </AccessControl>
<CodeAccess :value="['AC_100100', 'AC_100010']"> <AccessControl :value="['AC_100100', 'AC_100010']" type="code">
<Button class="mr-4"> <Button class="mr-4">
Super & Admin 账号可见 ["AC_100100","AC_1000001"] Super & Admin 账号可见 ["AC_100100","AC_1000001"]
</Button> </Button>
</CodeAccess> </AccessControl>
</div>
<div
v-if="accessMode === 'frontend'"
class="card-box mt-5 p-5 font-semibold"
>
<div class="mb-3 text-lg">组件形式控制 - 用户角色方式</div>
<AccessControl :value="['super']">
<Button class="mr-4"> Super 角色可见 </Button>
</AccessControl>
<AccessControl :value="['admin']">
<Button class="mr-4"> Admin 角色可见 </Button>
</AccessControl>
<AccessControl :value="['user']">
<Button class="mr-4"> User 角色可见 </Button>
</AccessControl>
<AccessControl :value="['super', 'admin']">
<Button class="mr-4"> Super & Admin 角色可见 </Button>
</AccessControl>
</div> </div>
<div class="card-box mt-5 p-5 font-semibold"> <div class="card-box mt-5 p-5 font-semibold">

8
apps/web-antd/src/views/demos/access/index.vue

@ -69,7 +69,9 @@ async function handleToggleAccessMode() {
<div class="card-box mt-5 p-5 font-semibold"> <div class="card-box mt-5 p-5 font-semibold">
<span class="text-lg">当前权限模式:</span> <span class="text-lg">当前权限模式:</span>
<span class="text-primary mx-4">{{ accessMode }}</span> <span class="text-primary mx-4">{{
accessMode === 'frontend' ? '前端权限控制' : '后端权限控制'
}}</span>
<Button type="primary" @click="handleToggleAccessMode"> <Button type="primary" @click="handleToggleAccessMode">
切换为{{ accessMode === 'frontend' ? '后端' : '前端' }}权限模式 切换为{{ accessMode === 'frontend' ? '后端' : '前端' }}权限模式
</Button> </Button>
@ -77,8 +79,8 @@ async function handleToggleAccessMode() {
<div class="card-box mt-5 p-5 font-semibold"> <div class="card-box mt-5 p-5 font-semibold">
<div class="mb-3"> <div class="mb-3">
<span class="text-lg">当前账号:</span> <span class="text-lg">当前账号:</span>
<span class="text-primary mx-4"> <span class="text-primary mx-4 text-lg">
{{ accessStore.userRoles }} {{ accessStore.userRoles?.[0] }}
</span> </span>
</div> </div>

2
apps/web-antd/src/views/demos/features/login-expired/index.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { LoginExpiredModeType } from '@vben-core/preferences'; import type { LoginExpiredModeType } from '@vben/types';
import { preferences, updatePreferences } from '@vben-core/preferences'; import { preferences, updatePreferences } from '@vben-core/preferences';

6
package.json

@ -88,12 +88,6 @@
"clsx": "^2.1.1", "clsx": "^2.1.1",
"vue": "^3.4.31" "vue": "^3.4.31"
}, },
"peerDependencyRules": {
"allowedVersions": {
"eslint": "*",
" @typescript-eslint/eslint-plugin": "*"
}
},
"neverBuiltDependencies": [ "neverBuiltDependencies": [
"canvas", "canvas",
"node-gyp", "node-gyp",

1
packages/@core/forward/helpers/package.json

@ -36,6 +36,7 @@
} }
}, },
"dependencies": { "dependencies": {
"@vben-core/toolkit": "workspace:*",
"@vben-core/typings": "workspace:*", "@vben-core/typings": "workspace:*",
"vue-router": "^4.4.0" "vue-router": "^4.4.0"
} }

0
packages/business/access/src/generate-menu-and-routes/generate-menus.test.ts → packages/@core/forward/helpers/src/generate-menus.test.ts

2
packages/business/access/src/generate-menu-and-routes/generate-menus.ts → packages/@core/forward/helpers/src/generate-menus.ts

@ -1,4 +1,4 @@
import type { ExRouteRecordRaw, MenuRecordRaw } from '@vben/types'; import type { ExRouteRecordRaw, MenuRecordRaw } from '@vben-core/typings';
import type { RouteRecordRaw, Router } from 'vue-router'; import type { RouteRecordRaw, Router } from 'vue-router';
import { mapTree } from '@vben-core/toolkit'; import { mapTree } from '@vben-core/toolkit';

20
packages/business/access/src/generate-menu-and-routes/generate-routes-backend.ts → packages/@core/forward/helpers/src/generate-routes-backend.ts

@ -1,19 +1,17 @@
import type {
ComponentRecordType,
RouteRecordStringComponent,
} from '@vben/types';
import type { RouteRecordRaw } from 'vue-router'; import type { RouteRecordRaw } from 'vue-router';
import type { GeneratorMenuAndRoutesOptions } from '../types';
import { $t } from '@vben-core/locales';
import { mapTree } from '@vben-core/toolkit'; import { mapTree } from '@vben-core/toolkit';
import {
ComponentRecordType,
GenerateMenuAndRoutesOptions,
RouteRecordStringComponent,
} from '@vben-core/typings';
/** /**
* 动态生成路由 - 后端方式 * 动态生成路由 - 后端方式
*/ */
async function generateRoutesByBackend( async function generateRoutesByBackend(
options: GeneratorMenuAndRoutesOptions, options: GenerateMenuAndRoutesOptions,
): Promise<RouteRecordRaw[]> { ): Promise<RouteRecordRaw[]> {
const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options; const { fetchMenuListAsync, layoutMap = {}, pageMap = {} } = options;
@ -65,11 +63,6 @@ function convertRoutes(
]; ];
} }
// 国际化转化
if (route.meta?.title) {
route.meta.title = $t(route.meta.title);
}
return route; return route;
}); });
} }
@ -83,6 +76,7 @@ function normalizeViewPath(path: string): string {
? normalizedPath ? normalizedPath
: `/${normalizedPath}`; : `/${normalizedPath}`;
// TODO: 这里耦合了vben-admin的目录结构
return viewPath.replace(/^\/views/, ''); return viewPath.replace(/^\/views/, '');
} }
export { generateRoutesByBackend }; export { generateRoutesByBackend };

0
packages/business/access/src/generate-menu-and-routes/generate-routes-frontend.test.ts → packages/@core/forward/helpers/src/generate-routes-frontend.test.ts

1
packages/business/access/src/generate-menu-and-routes/generate-routes-frontend.ts → packages/@core/forward/helpers/src/generate-routes-frontend.ts

@ -1,6 +1,7 @@
import type { RouteRecordRaw } from 'vue-router'; import type { RouteRecordRaw } from 'vue-router';
import { filterTree, mapTree } from '@vben-core/toolkit'; import { filterTree, mapTree } from '@vben-core/toolkit';
/** /**
* 动态生成路由 - 前端方式 * 动态生成路由 - 前端方式
*/ */

3
packages/@core/forward/helpers/src/index.ts

@ -1,2 +1,5 @@
export * from './find-menu-by-path'; export * from './find-menu-by-path';
export * from './generate-menus';
export * from './generate-routes-backend';
export * from './generate-routes-frontend';
export * from './merge-route-modules'; export * from './merge-route-modules';

2
packages/@core/forward/preferences/package.json

@ -29,8 +29,6 @@
} }
}, },
"dependencies": { "dependencies": {
"@vben-core/cache": "workspace:*",
"@vben-core/colorful": "workspace:*",
"@vben-core/toolkit": "workspace:*", "@vben-core/toolkit": "workspace:*",
"@vben-core/typings": "workspace:*", "@vben-core/typings": "workspace:*",
"@vueuse/core": "^10.11.0", "@vueuse/core": "^10.11.0",

7
packages/@core/forward/preferences/src/constants.ts

@ -1,6 +1,7 @@
import type { BuiltinThemeType } from '@vben-core/typings'; import type {
BuiltinThemeType,
import type { SupportedLanguagesType } from './types'; SupportedLanguagesType,
} from '@vben-core/typings';
interface Language { interface Language {
key: SupportedLanguagesType; key: SupportedLanguagesType;

11
packages/@core/forward/preferences/src/preferences.test.ts

@ -5,17 +5,6 @@ import { PreferenceManager, isDarkTheme } from './preferences';
describe('preferences', () => { describe('preferences', () => {
let preferenceManager: PreferenceManager; let preferenceManager: PreferenceManager;
vi.mock('@vben-core/cache', () => {
return {
StorageManager: vi.fn().mockImplementation(() => {
return {
getItem: vi.fn(),
removeItem: vi.fn(),
setItem: vi.fn(),
};
}),
};
});
// 模拟 window.matchMedia 方法 // 模拟 window.matchMedia 方法
vi.stubGlobal( vi.stubGlobal(

9
packages/@core/forward/preferences/src/preferences.ts

@ -4,9 +4,12 @@ import type { Preferences } from './types';
import { markRaw, reactive, readonly, watch } from 'vue'; import { markRaw, reactive, readonly, watch } from 'vue';
import { StorageManager } from '@vben-core/cache'; import {
import { generatorColorVariables } from '@vben-core/colorful'; StorageManager,
import { merge, updateCSSVariables } from '@vben-core/toolkit'; generatorColorVariables,
merge,
updateCSSVariables,
} from '@vben-core/toolkit';
import { import {
breakpointsTailwind, breakpointsTailwind,

33
packages/@core/forward/preferences/src/types.ts

@ -1,28 +1,18 @@
import type { import type {
AccessModeType,
AuthPageLayoutType,
BreadcrumbStyleType,
BuiltinThemeType, BuiltinThemeType,
ContentCompactType, ContentCompactType,
LayoutHeaderModeType, LayoutHeaderModeType,
LayoutType, LayoutType,
LoginExpiredModeType,
NavigationStyleType,
PageTransitionType,
SupportedLanguagesType, SupportedLanguagesType,
ThemeModeType, ThemeModeType,
} from '@vben-core/typings'; } from '@vben-core/typings';
/**
* 登录过期模式
* 'modal' 弹窗模式 | 'page' 页面模式
*/
type LoginExpiredModeType = 'modal' | 'page';
type BreadcrumbStyleType = 'background' | 'normal';
type AccessModeType = 'allow-all' | 'backend' | 'frontend';
type NavigationStyleType = 'plain' | 'rounded';
type PageTransitionType = 'fade' | 'fade-down' | 'fade-slide' | 'fade-up';
type AuthPageLayoutType = 'panel-center' | 'panel-left' | 'panel-right';
interface AppPreferences { interface AppPreferences {
/** 权限模式 */ /** 权限模式 */
accessMode: AccessModeType; accessMode: AccessModeType;
@ -236,28 +226,17 @@ interface Preferences {
type PreferencesKeys = keyof Preferences; type PreferencesKeys = keyof Preferences;
export type { export type {
AccessModeType,
AppPreferences, AppPreferences,
AuthPageLayoutType,
BreadcrumbPreferences, BreadcrumbPreferences,
BreadcrumbStyleType,
ContentCompactType,
FooterPreferences, FooterPreferences,
HeaderPreferences, HeaderPreferences,
LayoutHeaderModeType,
LayoutType,
LoginExpiredModeType,
LogoPreferences, LogoPreferences,
NavigationPreferences, NavigationPreferences,
NavigationStyleType,
PageTransitionType,
Preferences, Preferences,
PreferencesKeys, PreferencesKeys,
ShortcutKeyPreferences, ShortcutKeyPreferences,
SidebarPreferences, SidebarPreferences,
SupportedLanguagesType,
TabbarPreferences, TabbarPreferences,
ThemeModeType,
ThemePreferences, ThemePreferences,
TransitionPreferences, TransitionPreferences,
WidgetPreferences, WidgetPreferences,

7
packages/@core/shared/cache/build.config.ts

@ -1,7 +0,0 @@
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
clean: true,
declaration: true,
entries: ['src/index'],
});

40
packages/@core/shared/cache/package.json

@ -1,40 +0,0 @@
{
"name": "@vben-core/cache",
"version": "5.0.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
"type": "git",
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
"directory": "packages/@vben-core/shared/cache"
},
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm unbuild",
"stub": "pnpm unbuild --stub"
},
"files": [
"dist"
],
"sideEffects": false,
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"default": "./dist/index.mjs"
}
},
"publishConfig": {
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
}
}
},
"dependencies": {},
"devDependencies": {}
}

6
packages/@core/shared/cache/tsconfig.json

@ -1,6 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/library.json",
"include": ["src"],
"exclude": ["node_modules"]
}

7
packages/@core/shared/colorful/build.config.ts

@ -1,7 +0,0 @@
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
clean: true,
declaration: true,
entries: ['src/index'],
});

42
packages/@core/shared/colorful/package.json

@ -1,42 +0,0 @@
{
"name": "@vben-core/colorful",
"version": "5.0.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
"type": "git",
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
"directory": "packages/@vben-core/shared/colorful"
},
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm unbuild",
"stub": "pnpm unbuild --stub"
},
"files": [
"dist"
],
"sideEffects": false,
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"default": "./dist/index.mjs"
}
},
"publishConfig": {
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
}
}
},
"dependencies": {
"@ant-design/colors": "^7.1.0",
"@ctrl/tinycolor": "^4.1.0"
}
}

6
packages/@core/shared/colorful/tsconfig.json

@ -1,6 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/library.json",
"include": ["src"],
"exclude": ["node_modules"]
}

3
packages/@core/shared/design-tokens/README.md

@ -1,3 +0,0 @@
# @vben-core/design-tokens
用于维护全局所有的 css 变量,它由 vite 插件在全局注入,不需要手动引入

39
packages/@core/shared/design-tokens/package.json

@ -1,39 +0,0 @@
{
"name": "@vben-core/design-tokens",
"version": "5.0.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
"type": "git",
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
"directory": "packages/@vben-core/shared/design-tokens"
},
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm vite build",
"dts": "vue-tsc --declaration --emitDeclarationOnly --declarationDir dist",
"prepublishOnly": "npm run build"
},
"files": [
"dist"
],
"sideEffects": [
"**/*.css"
],
"main": "./dist/index.css",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"default": "./dist/index.css"
}
},
"publishConfig": {
"exports": {
".": {
"default": "./dist/index.mjs"
}
}
}
}

6
packages/@core/shared/design-tokens/tsconfig.json

@ -1,6 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/library.json",
"include": ["src"],
"exclude": ["node_modules"]
}

3
packages/@core/shared/design-tokens/vite.config.mts

@ -1,3 +0,0 @@
import { defineConfig } from '@vben/vite-config';
export default defineConfig();

0
packages/@core/shared/design-tokens/src/dark/index.css → packages/@core/shared/design/src/design-tokens/dark/index.css

0
packages/@core/shared/design-tokens/src/default/index.css → packages/@core/shared/design/src/design-tokens/default/index.css

0
packages/@core/shared/design-tokens/src/index.ts → packages/@core/shared/design/src/design-tokens/index.ts

1
packages/@core/shared/design/src/index.ts

@ -1,5 +1,6 @@
import './scss/index.scss'; import './scss/index.scss';
import './css/tailwind.css'; import './css/tailwind.css';
import './css/nprogress.css'; import './css/nprogress.css';
import './design-tokens';
export {}; export {};

2
packages/@core/shared/toolkit/package.json

@ -36,6 +36,8 @@
} }
}, },
"dependencies": { "dependencies": {
"@ant-design/colors": "^7.1.0",
"@ctrl/tinycolor": "^4.1.0",
"@vue/shared": "^3.4.31", "@vue/shared": "^3.4.31",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"defu": "^6.1.4", "defu": "^6.1.4",

0
packages/@core/shared/cache/src/index.ts → packages/@core/shared/toolkit/src/cache/index.ts

0
packages/@core/shared/cache/src/storage-manager.test.ts → packages/@core/shared/toolkit/src/cache/storage-manager.test.ts

0
packages/@core/shared/cache/src/storage-manager.ts → packages/@core/shared/toolkit/src/cache/storage-manager.ts

0
packages/@core/shared/cache/src/types.ts → packages/@core/shared/toolkit/src/cache/types.ts

2
packages/@core/shared/colorful/src/utils.test.ts → packages/@core/shared/toolkit/src/colorful/convert.test.ts

@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { convertToHsl, convertToHslCssVar, isValidColor } from './utils'; import { convertToHsl, convertToHslCssVar, isValidColor } from './convert';
describe('color conversion functions', () => { describe('color conversion functions', () => {
it('should correctly convert color to HSL format', () => { it('should correctly convert color to HSL format', () => {

0
packages/@core/shared/colorful/src/utils.ts → packages/@core/shared/toolkit/src/colorful/convert.ts

2
packages/@core/shared/colorful/src/generator.ts → packages/@core/shared/toolkit/src/colorful/generator.ts

@ -1,6 +1,6 @@
import { generate } from '@ant-design/colors'; import { generate } from '@ant-design/colors';
import { convertToHslCssVar } from './utils'; import { convertToHslCssVar } from './convert';
export * from '@ant-design/colors'; export * from '@ant-design/colors';

2
packages/@core/shared/colorful/src/index.ts → packages/@core/shared/toolkit/src/colorful/index.ts

@ -1,2 +1,2 @@
export * from './convert';
export * from './generator'; export * from './generator';
export * from './utils';

2
packages/@core/shared/toolkit/src/index.ts

@ -1,4 +1,6 @@
export * from './cache';
export * from './cn'; export * from './cn';
export * from './colorful';
export * from './diff'; export * from './diff';
export * from './dom'; export * from './dom';
export * from './inference'; export * from './inference';

22
packages/@core/shared/typings/src/app.d.ts

@ -33,11 +33,33 @@ type ContentCompactType = 'compact' | 'wide';
type LayoutHeaderModeType = 'auto' | 'auto-scroll' | 'fixed' | 'static'; type LayoutHeaderModeType = 'auto' | 'auto-scroll' | 'fixed' | 'static';
/**
* 登录过期模式
* 'modal' 弹窗模式 | 'page' 页面模式
*/
type LoginExpiredModeType = 'modal' | 'page';
type BreadcrumbStyleType = 'background' | 'normal';
type AccessModeType = 'allow-all' | 'backend' | 'frontend';
type NavigationStyleType = 'plain' | 'rounded';
type PageTransitionType = 'fade' | 'fade-down' | 'fade-slide' | 'fade-up';
type AuthPageLayoutType = 'panel-center' | 'panel-left' | 'panel-right';
export type { export type {
AccessModeType,
AuthPageLayoutType,
BreadcrumbStyleType,
BuiltinThemeType, BuiltinThemeType,
ContentCompactType, ContentCompactType,
LayoutHeaderModeType, LayoutHeaderModeType,
LayoutType, LayoutType,
LoginExpiredModeType,
NavigationStyleType,
PageTransitionType,
SupportedLanguagesType, SupportedLanguagesType,
ThemeModeType, ThemeModeType,
}; };

33
packages/@core/shared/typings/src/basic.d.ts

@ -0,0 +1,33 @@
interface BasicOption {
label: string;
value: string;
}
interface SelectOption extends BasicOption {}
interface TabsOption extends BasicOption {}
interface BasicUserInfo {
/**
* 头像
*/
avatar: string;
/**
* 用户昵称
*/
realName: string;
/**
* 用户角色
*/
roles?: string[];
/**
* 用户id
*/
userId: string;
/**
* 用户名
*/
username: string;
}
export type { BasicOption, BasicUserInfo, SelectOption, TabsOption };

1
packages/@core/shared/typings/src/index.ts

@ -1,4 +1,5 @@
export type * from './app'; export type * from './app';
export * from './basic';
export type * from './helper'; export type * from './helper';
export type * from './menu-record'; export type * from './menu-record';
export type * from './tabs'; export type * from './tabs';

29
packages/@core/shared/typings/src/vue-router.d.ts

@ -1,3 +1,7 @@
import type { RouteRecordRaw, Router } from 'vue-router';
import type { Component } from 'vue';
interface RouteMeta { interface RouteMeta {
/** /**
* 是否固定标签页 * 是否固定标签页
@ -91,4 +95,27 @@ interface RouteMeta {
title: string; title: string;
} }
export type { RouteMeta }; // 定义递归类型以将 RouteRecordRaw 的 component 属性更改为 string
type RouteRecordStringComponent<T = string> = {
children?: RouteRecordStringComponent<T>[];
component: T;
} & Omit<RouteRecordRaw, 'children' | 'component'>;
type ComponentRecordType = Record<string, () => Promise<Component>>;
interface GenerateMenuAndRoutesOptions {
fetchMenuListAsync?: () => Promise<RouteRecordStringComponent[]>;
forbiddenComponent?: RouteRecordRaw['component'];
layoutMap?: ComponentRecordType;
pageMap?: ComponentRecordType;
roles?: string[];
router: Router;
routes: RouteRecordRaw[];
}
export type {
ComponentRecordType,
GenerateMenuAndRoutesOptions,
RouteMeta,
RouteRecordStringComponent,
};

1
packages/@core/ui-kit/shadcn-ui/package.json

@ -43,7 +43,6 @@
}, },
"dependencies": { "dependencies": {
"@radix-icons/vue": "^1.0.0", "@radix-icons/vue": "^1.0.0",
"@vben-core/colorful": "workspace:*",
"@vben-core/iconify": "workspace:*", "@vben-core/iconify": "workspace:*",
"@vben-core/toolkit": "workspace:*", "@vben-core/toolkit": "workspace:*",
"@vben-core/typings": "workspace:*", "@vben-core/typings": "workspace:*",

2
packages/@core/ui-kit/shadcn-ui/src/components/menu-badge/menu-badge.vue

@ -3,7 +3,7 @@ import type { MenuRecordBadgeRaw } from '@vben-core/typings';
import { computed } from 'vue'; import { computed } from 'vue';
import { isValidColor } from '@vben-core/colorful'; import { isValidColor } from '@vben-core/toolkit';
import BadgeDot from './menu-badge-dot.vue'; import BadgeDot from './menu-badge-dot.vue';

9
packages/business/access/package.json

@ -37,14 +37,11 @@
} }
}, },
"dependencies": { "dependencies": {
"@vben-core/locales": "workspace:*", "@vben-core/helpers": "workspace:*",
"@vben-core/preferences": "workspace:*", "@vben-core/preferences": "workspace:*",
"@vben-core/stores": "workspace:*", "@vben-core/stores": "workspace:*",
"@vben-core/toolkit": "workspace:*", "@vben-core/toolkit": "workspace:*",
"vue": "^3.4.31", "@vben-core/typings": "workspace:*",
"vue-router": "^4.4.0" "vue": "^3.4.31"
},
"devDependencies": {
"@vben/types": "workspace:*"
} }
} }

43
packages/business/access/src/access-control.vue

@ -0,0 +1,43 @@
<!--
Access control component for fine-grained access control.
-->
<script lang="ts" setup>
import { computed } from 'vue';
import { useAccess } from './use-access';
interface Props {
/**
* 通过什么方式来控制组件,如果是 role,则传入角色,如果是 code,则传入权限码
* @default 'role'
*/
type?: 'code' | 'role';
/**
* Specified codes is visible
* @default []
*/
value?: string[];
}
defineOptions({
name: 'AccessControl',
});
const props = withDefaults(defineProps<Props>(), {
type: 'role',
value: () => [],
});
const { hasAuthByCodes, hasAuthByRoles } = useAccess();
const hasAuth = computed(() => {
const { type, value } = props;
return type === 'role' ? hasAuthByRoles(value) : hasAuthByCodes(value);
});
</script>
<template>
<slot v-if="!value"></slot>
<slot v-else-if="hasAuth"></slot>
</template>

29
packages/business/access/src/code-access.vue

@ -1,29 +0,0 @@
<!--
Access control component for fine-grained access control.
-->
<script lang="ts" setup>
import { useAccess } from './use-access';
interface Props {
/**
* Specified codes is visible
* @default []
*/
value?: string[];
}
defineOptions({
name: 'CodeAccess',
});
withDefaults(defineProps<Props>(), {
value: () => [],
});
const { hasAuthByCodes } = useAccess();
</script>
<template>
<slot v-if="!value"></slot>
<slot v-else-if="hasAuthByCodes(value)"></slot>
</template>

45
packages/business/access/src/generate-menu-and-routes/index.ts → packages/business/access/src/generate-accessible.ts

@ -1,17 +1,18 @@
import type { AccessModeType } from '@vben-core/preferences'; import type {
import type { RouteRecordRaw } from 'vue-router'; AccessModeType,
GenerateMenuAndRoutesOptions,
import type { GeneratorMenuAndRoutesOptions } from '../types'; } from '@vben-core/typings';
import {
generateMenus,
generateRoutesByBackend,
generateRoutesByFrontend,
} from '@vben-core/helpers';
import { cloneDepp } from '@vben-core/toolkit'; import { cloneDepp } from '@vben-core/toolkit';
import { generateMenus } from './generate-menus'; async function generateAccessible(
import { generateRoutesByBackend } from './generate-routes-backend';
import { generateRoutesByFrontend } from './generate-routes-frontend';
async function generateMenusAndRoutes(
mode: AccessModeType, mode: AccessModeType,
options: GeneratorMenuAndRoutesOptions, options: GenerateMenuAndRoutesOptions,
) { ) {
const { router } = options; const { router } = options;
@ -25,7 +26,7 @@ async function generateMenusAndRoutes(
}); });
// 生成菜单 // 生成菜单
const accessibleMenus = await generateMenus1(mode, accessibleRoutes, options); const accessibleMenus = await generateMenus(accessibleRoutes, options.router);
return { accessibleMenus, accessibleRoutes }; return { accessibleMenus, accessibleRoutes };
} }
@ -36,7 +37,7 @@ async function generateMenusAndRoutes(
*/ */
async function generateRoutes( async function generateRoutes(
mode: AccessModeType, mode: AccessModeType,
options: GeneratorMenuAndRoutesOptions, options: GenerateMenuAndRoutesOptions,
) { ) {
const { forbiddenComponent, roles, routes } = options; const { forbiddenComponent, roles, routes } = options;
@ -61,22 +62,4 @@ async function generateRoutes(
} }
} }
async function generateMenus1( export { generateAccessible };
mode: AccessModeType,
routes: RouteRecordRaw[],
options: GeneratorMenuAndRoutesOptions,
) {
const { router } = options;
switch (mode) {
case 'allow-all':
case 'frontend':
case 'backend': {
return await generateMenus(routes, router);
}
default: {
return [];
}
}
}
export { generateMenusAndRoutes };

6
packages/business/access/src/index.ts

@ -1,5 +1,3 @@
export { default as CodeAccess } from './code-access.vue'; export { default as AccessControl } from './access-control.vue';
export * from './generate-menu-and-routes'; export * from './generate-accessible';
export { default as RoleAccess } from './role-access.vue';
export type * from './types';
export * from './use-access'; export * from './use-access';

29
packages/business/access/src/role-access.vue

@ -1,29 +0,0 @@
<!--
Access control component for fine-grained access control.
-->
<script lang="ts" setup>
import { useAccess } from './use-access';
interface Props {
/**
* Specified role is visible
* @default []
*/
value?: string[];
}
defineOptions({
name: 'RoleAccess',
});
withDefaults(defineProps<Props>(), {
value: undefined,
});
const { hasAuthByRoles } = useAccess();
</script>
<template>
<slot v-if="!value"></slot>
<slot v-else-if="hasAuthByRoles(value)"></slot>
</template>

17
packages/business/access/src/types.ts

@ -1,17 +0,0 @@
import type {
ComponentRecordType,
RouteRecordStringComponent,
} from '@vben/types';
import type { RouteRecordRaw, Router } from 'vue-router';
interface GeneratorMenuAndRoutesOptions {
fetchMenuListAsync?: () => Promise<RouteRecordStringComponent[]>;
forbiddenComponent?: RouteRecordRaw['component'];
layoutMap?: ComponentRecordType;
pageMap?: ComponentRecordType;
roles?: string[];
router: Router;
routes: RouteRecordRaw[];
}
export type { GeneratorMenuAndRoutesOptions };

3
packages/business/access/tsconfig.json

@ -1,9 +1,6 @@
{ {
"$schema": "https://json.schemastore.org/tsconfig", "$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/web.json", "extends": "@vben/tsconfig/web.json",
"compilerOptions": {
"types": ["@vben/types/global"]
},
"include": ["src"], "include": ["src"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

6
packages/business/layouts/package.json

@ -37,7 +37,6 @@
} }
}, },
"dependencies": { "dependencies": {
"@vben-core/colorful": "workspace:*",
"@vben-core/helpers": "workspace:*", "@vben-core/helpers": "workspace:*",
"@vben-core/iconify": "workspace:*", "@vben-core/iconify": "workspace:*",
"@vben-core/layout-ui": "workspace:*", "@vben-core/layout-ui": "workspace:*",
@ -48,12 +47,9 @@
"@vben-core/stores": "workspace:*", "@vben-core/stores": "workspace:*",
"@vben-core/tabs-ui": "workspace:*", "@vben-core/tabs-ui": "workspace:*",
"@vben-core/toolkit": "workspace:*", "@vben-core/toolkit": "workspace:*",
"@vben-core/typings": "workspace:*",
"@vueuse/core": "^10.11.0", "@vueuse/core": "^10.11.0",
"vue": "^3.4.31", "vue": "^3.4.31",
"vue-router": "^4.4.0" "vue-router": "^4.4.0"
},
"devDependencies": {
"@vben-core/typings": "workspace:*",
"@vben/types": "workspace:*"
} }
} }

29
packages/business/layouts/src/basic/tabbar/use-tabs.ts

@ -126,6 +126,19 @@ function useTabs() {
disabled || !isCurrentTab || tabs.length - affixTabs.length <= 1; disabled || !isCurrentTab || tabs.length - affixTabs.length <= 1;
const menus: IContextMenuItem[] = [ const menus: IContextMenuItem[] = [
{
handler: async () => {
if (!contentIsMaximize.value) {
await router.push(tab.fullPath);
}
updateContentScreen(!contentIsMaximize.value);
},
icon: contentIsMaximize.value ? IcRoundFitScreen : IcTwotoneFitScreen,
key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
text: contentIsMaximize.value
? $t('preferences.tabbar.contextMenu.restoreMaximize')
: $t('preferences.tabbar.contextMenu.maximize'),
},
{ {
disabled: !isCurrentTab, disabled: !isCurrentTab,
handler: async () => { handler: async () => {
@ -166,22 +179,10 @@ function useTabs() {
}, },
icon: IcRoundTableView, icon: IcRoundTableView,
key: 'open-in-new-window', key: 'open-in-new-window',
text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
},
{
handler: async () => {
if (!contentIsMaximize.value) {
await router.push(tab.fullPath);
}
updateContentScreen(!contentIsMaximize.value);
},
icon: contentIsMaximize.value ? IcRoundFitScreen : IcTwotoneFitScreen,
key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
separator: true, separator: true,
text: contentIsMaximize.value text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
? $t('preferences.tabbar.contextMenu.restoreMaximize')
: $t('preferences.tabbar.contextMenu.maximize'),
}, },
{ {
disabled: closeLeftDisabled, disabled: closeLeftDisabled,
handler: async () => { handler: async () => {

2
packages/business/layouts/src/widgets/breadcrumb.vue

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { BreadcrumbStyleType } from '@vben-core/preferences';
import type { IBreadcrumb } from '@vben-core/shadcn-ui'; import type { IBreadcrumb } from '@vben-core/shadcn-ui';
import type { BreadcrumbStyleType } from '@vben-core/typings';
import { computed } from 'vue'; import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';

2
packages/business/layouts/src/widgets/color-toggle.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { BuiltinThemeType } from '@vben/types'; import type { BuiltinThemeType } from '@vben-core/typings';
import { IcRoundColorLens } from '@vben-core/iconify'; import { IcRoundColorLens } from '@vben-core/iconify';
import { import {

2
packages/business/layouts/src/widgets/global-search/global-search.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben-core/typings';
import { onMounted, onUnmounted, ref, watch } from 'vue'; import { onMounted, onUnmounted, ref, watch } from 'vue';

2
packages/business/layouts/src/widgets/global-search/search-panel.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { MenuRecordRaw } from '@vben/types'; import type { MenuRecordRaw } from '@vben-core/typings';
import { nextTick, onMounted, ref, shallowRef, watch } from 'vue'; import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';

2
packages/business/layouts/src/widgets/language-toggle.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SupportedLanguagesType } from '@vben/types'; import type { SupportedLanguagesType } from '@vben-core/typings';
import { IcBaselineLanguage } from '@vben-core/iconify'; import { IcBaselineLanguage } from '@vben-core/iconify';
import { loadLocaleMessages } from '@vben-core/locales'; import { loadLocaleMessages } from '@vben-core/locales';

2
packages/business/layouts/src/widgets/layout-toggle.vue

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AuthPageLayoutType } from '@vben-core/preferences';
import type { VbenDropdownMenuItem } from '@vben-core/shadcn-ui'; import type { VbenDropdownMenuItem } from '@vben-core/shadcn-ui';
import type { AuthPageLayoutType } from '@vben-core/typings';
import { computed } from 'vue'; import { computed } from 'vue';

4
packages/business/layouts/src/widgets/preferences/blocks/general/general.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
import { SUPPORT_LANGUAGES } from '@vben-core/preferences'; import { SUPPORT_LANGUAGES } from '@vben-core/preferences';
@ -14,7 +14,7 @@ defineOptions({
const appLocale = defineModel<string>('appLocale'); const appLocale = defineModel<string>('appLocale');
const appDynamicTitle = defineModel<boolean>('appDynamicTitle'); const appDynamicTitle = defineModel<boolean>('appDynamicTitle');
const localeItems: SelectListItem[] = SUPPORT_LANGUAGES.map((item) => ({ const localeItems: SelectOption[] = SUPPORT_LANGUAGES.map((item) => ({
label: item.text, label: item.text,
value: item.key, value: item.key,
})); }));

4
packages/business/layouts/src/widgets/preferences/blocks/input-item.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue'; import { useSlots } from 'vue';
@ -13,7 +13,7 @@ defineOptions({
withDefaults( withDefaults(
defineProps<{ defineProps<{
disabled?: boolean; disabled?: boolean;
items?: SelectListItem[]; items?: SelectOption[];
placeholder?: string; placeholder?: string;
}>(), }>(),
{ {

4
packages/business/layouts/src/widgets/preferences/blocks/layout/breadcrumb.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { computed } from 'vue'; import { computed } from 'vue';
@ -20,7 +20,7 @@ const breadcrumbStyleType = defineModel<string>('breadcrumbStyleType');
const breadcrumbShowHome = defineModel<boolean>('breadcrumbShowHome'); const breadcrumbShowHome = defineModel<boolean>('breadcrumbShowHome');
const breadcrumbHideOnlyOne = defineModel<boolean>('breadcrumbHideOnlyOne'); const breadcrumbHideOnlyOne = defineModel<boolean>('breadcrumbHideOnlyOne');
const typeItems: SelectListItem[] = [ const typeItems: SelectOption[] = [
{ label: $t('preferences.normal'), value: 'normal' }, { label: $t('preferences.normal'), value: 'normal' },
{ label: $t('preferences.breadcrumb.background'), value: 'background' }, { label: $t('preferences.breadcrumb.background'), value: 'background' },
]; ];

4
packages/business/layouts/src/widgets/preferences/blocks/layout/header.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { LayoutHeaderModeType, SelectListItem } from '@vben/types'; import type { LayoutHeaderModeType, SelectOption } from '@vben-core/typings';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
@ -15,7 +15,7 @@ defineProps<{ disabled: boolean }>();
const headerEnable = defineModel<boolean>('headerEnable'); const headerEnable = defineModel<boolean>('headerEnable');
const headerMode = defineModel<LayoutHeaderModeType>('headerMode'); const headerMode = defineModel<LayoutHeaderModeType>('headerMode');
const localeItems: SelectListItem[] = [ const localeItems: SelectOption[] = [
{ {
label: $t('preferences.header.modeStatic'), label: $t('preferences.header.modeStatic'),
value: 'static', value: 'static',

2
packages/business/layouts/src/widgets/preferences/blocks/layout/layout.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { LayoutType } from '@vben/types'; import type { LayoutType } from '@vben-core/typings';
import { type Component, computed } from 'vue'; import { type Component, computed } from 'vue';

4
packages/business/layouts/src/widgets/preferences/blocks/layout/navigation.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
@ -16,7 +16,7 @@ const navigationStyleType = defineModel<string>('navigationStyleType');
const navigationSplit = defineModel<boolean>('navigationSplit'); const navigationSplit = defineModel<boolean>('navigationSplit');
const navigationAccordion = defineModel<boolean>('navigationAccordion'); const navigationAccordion = defineModel<boolean>('navigationAccordion');
const stylesItems: SelectListItem[] = [ const stylesItems: SelectOption[] = [
{ label: $t('preferences.rounded'), value: 'rounded' }, { label: $t('preferences.rounded'), value: 'rounded' },
{ label: $t('preferences.plain'), value: 'plain' }, { label: $t('preferences.plain'), value: 'plain' },
]; ];

4
packages/business/layouts/src/widgets/preferences/blocks/number-field-item.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue'; import { useSlots } from 'vue';
@ -20,7 +20,7 @@ defineOptions({
withDefaults( withDefaults(
defineProps<{ defineProps<{
disabled?: boolean; disabled?: boolean;
items?: SelectListItem[]; items?: SelectOption[];
placeholder?: string; placeholder?: string;
}>(), }>(),
{ {

4
packages/business/layouts/src/widgets/preferences/blocks/select-item.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { useSlots } from 'vue'; import { useSlots } from 'vue';
@ -20,7 +20,7 @@ defineOptions({
withDefaults( withDefaults(
defineProps<{ defineProps<{
disabled?: boolean; disabled?: boolean;
items?: SelectListItem[]; items?: SelectOption[];
placeholder?: string; placeholder?: string;
}>(), }>(),
{ {

4
packages/business/layouts/src/widgets/preferences/blocks/theme/builtin.vue

@ -1,15 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { BuiltinThemeType } from '@vben/types'; import type { BuiltinThemeType } from '@vben-core/typings';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { TinyColor, convertToHsl } from '@vben-core/colorful';
import { MdiEditBoxOutline } from '@vben-core/iconify'; import { MdiEditBoxOutline } from '@vben-core/iconify';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
import { import {
BUILT_IN_THEME_PRESETS, BUILT_IN_THEME_PRESETS,
type BuiltinThemePreset, type BuiltinThemePreset,
} from '@vben-core/preferences'; } from '@vben-core/preferences';
import { TinyColor, convertToHsl } from '@vben-core/toolkit';
defineOptions({ defineOptions({
name: 'PreferenceBuiltinTheme', name: 'PreferenceBuiltinTheme',

2
packages/business/layouts/src/widgets/preferences/blocks/theme/theme.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ThemeModeType } from '@vben-core/preferences'; import type { ThemeModeType } from '@vben-core/typings';
import type { Component } from 'vue'; import type { Component } from 'vue';

4
packages/business/layouts/src/widgets/preferences/blocks/toggle-item.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SelectListItem } from '@vben/types'; import type { SelectOption } from '@vben-core/typings';
import { ToggleGroup, ToggleGroupItem } from '@vben-core/shadcn-ui'; import { ToggleGroup, ToggleGroupItem } from '@vben-core/shadcn-ui';
@ -7,7 +7,7 @@ defineOptions({
name: 'PreferenceToggleItem', name: 'PreferenceToggleItem',
}); });
withDefaults(defineProps<{ disabled?: boolean; items: SelectListItem[] }>(), { withDefaults(defineProps<{ disabled?: boolean; items: SelectOption[] }>(), {
disabled: false, disabled: false,
items: () => [], items: () => [],
}); });

10
packages/business/layouts/src/widgets/preferences/preferences-sheet.vue

@ -1,17 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import type { SegmentedItem } from '@vben-core/shadcn-ui';
import type { import type {
BreadcrumbStyleType,
BuiltinThemeType, BuiltinThemeType,
ContentCompactType, ContentCompactType,
LayoutHeaderModeType, LayoutHeaderModeType,
LayoutType, LayoutType,
NavigationStyleType,
SupportedLanguagesType, SupportedLanguagesType,
ThemeModeType, ThemeModeType,
} from '@vben/types'; } from '@vben-core/typings';
import type {
BreadcrumbStyleType,
NavigationStyleType,
} from '@vben-core/preferences';
import type { SegmentedItem } from '@vben-core/shadcn-ui';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';

9
packages/business/layouts/src/widgets/preferences/preferences.vue

@ -1,6 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'; import { computed } from 'vue';
import { loadLocaleMessages } from '@vben-core/locales';
import { preferences, updatePreferences } from '@vben-core/preferences'; import { preferences, updatePreferences } from '@vben-core/preferences';
import { capitalizeFirstLetter } from '@vben-core/toolkit'; import { capitalizeFirstLetter } from '@vben-core/toolkit';
@ -29,8 +30,14 @@ const listen = computed(() => {
for (const [key, value] of Object.entries(preferences)) { for (const [key, value] of Object.entries(preferences)) {
if (typeof value === 'object') { if (typeof value === 'object') {
for (const subKey of Object.keys(value)) { for (const subKey of Object.keys(value)) {
result[`update:${key}${capitalizeFirstLetter(subKey)}`] = (val: any) => result[`update:${key}${capitalizeFirstLetter(subKey)}`] = (
val: any,
) => {
updatePreferences({ [key]: { [subKey]: val } }); updatePreferences({ [key]: { [subKey]: val } });
if (key === 'app' && subKey === 'locale') {
loadLocaleMessages(val);
}
};
} }
} else { } else {
result[key] = value; result[key] = value;

3
packages/business/layouts/src/widgets/theme-toggle/theme-toggle.vue

@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ThemeModeType } from '@vben-core/typings';
import { import {
IcRoundMotionPhotosAuto, IcRoundMotionPhotosAuto,
IcRoundWbSunny, IcRoundWbSunny,
@ -6,7 +8,6 @@ import {
} from '@vben-core/iconify'; } from '@vben-core/iconify';
import { $t } from '@vben-core/locales'; import { $t } from '@vben-core/locales';
import { import {
type ThemeModeType,
preferences, preferences,
updatePreferences, updatePreferences,
usePreferences, usePreferences,

2
packages/business/layouts/src/widgets/user-dropdown/user-dropdown.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AnyFunction } from '@vben/types'; import type { AnyFunction } from '@vben-core/typings';
import type { Component } from 'vue'; import type { Component } from 'vue';
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';

4
packages/business/universal-ui/src/dashboard/analysis/analysis-charts-tabs.vue

@ -1,12 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import type { TabsItem } from '@vben/types'; import type { TabsOption } from '@vben/types';
import { computed } from 'vue'; import { computed } from 'vue';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@vben-core/shadcn-ui'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@vben-core/shadcn-ui';
interface Props { interface Props {
tabs: TabsItem[]; tabs: TabsOption[];
} }
defineOptions({ defineOptions({

7
packages/styles/package.json

@ -42,12 +42,7 @@
} }
} }
}, },
"peerDependencies": {
"@vben-core/design": "workspace:*",
"@vben-core/design-tokens": "workspace:*"
},
"dependencies": { "dependencies": {
"@vben-core/design": "workspace:*", "@vben-core/design": "workspace:*"
"@vben-core/design-tokens": "workspace:*"
} }
} }

1
packages/styles/src/index.ts

@ -1,2 +1 @@
import '@vben-core/design'; import '@vben-core/design';
import '@vben-core/design-tokens';

2
packages/types/src/index.ts

@ -1,4 +1,2 @@
export type * from './router';
export type * from './ui';
export type * from './user'; export type * from './user';
export type * from '@vben-core/typings'; export type * from '@vben-core/typings';

13
packages/types/src/router.ts

@ -1,13 +0,0 @@
import type { RouteRecordRaw } from 'vue-router';
import type { Component } from 'vue';
// 定义递归类型以将 RouteRecordRaw 的 component 属性更改为 string
type RouteRecordStringComponent<T = string> = {
children?: RouteRecordStringComponent<T>[];
component: T;
} & Omit<RouteRecordRaw, 'children' | 'component'>;
type ComponentRecordType = Record<string, () => Promise<Component>>;
export type { ComponentRecordType, RouteRecordStringComponent };

11
packages/types/src/ui.d.ts

@ -1,11 +0,0 @@
interface SelectListItem {
label: string;
value: string;
}
interface TabsItem {
label: string;
value: string;
}
export type { SelectListItem, TabsItem };

25
packages/types/src/user.d.ts

@ -1,9 +1,7 @@
import type { BasicUserInfo } from '@vben-core/typings';
/** 用户信息 */ /** 用户信息 */
interface UserInfo { interface UserInfo extends BasicUserInfo {
/**
* 头像
*/
avatar: string;
/** /**
* 用户描述 * 用户描述
*/ */
@ -12,26 +10,11 @@ interface UserInfo {
* 首页地址 * 首页地址
*/ */
homePath: string; homePath: string;
/**
* 用户昵称
*/
realName: string;
/**
* 用户角色信息
*/
roles: string[];
/** /**
* accessToken * accessToken
*/ */
token: string; token: string;
/**
* 用户id
*/
userId: string;
/**
* 用户名
*/
username: string;
} }
export type { UserInfo }; export type { UserInfo };

61
pnpm-lock.yaml

@ -559,6 +559,9 @@ importers:
packages/@core/forward/helpers: packages/@core/forward/helpers:
dependencies: dependencies:
'@vben-core/toolkit':
specifier: workspace:*
version: link:../../shared/toolkit
'@vben-core/typings': '@vben-core/typings':
specifier: workspace:* specifier: workspace:*
version: link:../../shared/typings version: link:../../shared/typings
@ -568,12 +571,6 @@ importers:
packages/@core/forward/preferences: packages/@core/forward/preferences:
dependencies: dependencies:
'@vben-core/cache':
specifier: workspace:*
version: link:../../shared/cache
'@vben-core/colorful':
specifier: workspace:*
version: link:../../shared/colorful
'@vben-core/toolkit': '@vben-core/toolkit':
specifier: workspace:* specifier: workspace:*
version: link:../../shared/toolkit version: link:../../shared/toolkit
@ -642,25 +639,12 @@ importers:
specifier: ^9.13.1 specifier: ^9.13.1
version: 9.13.1(vue@3.4.31(typescript@5.5.3)) version: 9.13.1(vue@3.4.31(typescript@5.5.3))
packages/@core/shared/cache: {}
packages/@core/shared/colorful:
dependencies:
'@ant-design/colors':
specifier: ^7.1.0
version: 7.1.0
'@ctrl/tinycolor':
specifier: ^4.1.0
version: 4.1.0
packages/@core/shared/design: packages/@core/shared/design:
dependencies: dependencies:
modern-normalize: modern-normalize:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
packages/@core/shared/design-tokens: {}
packages/@core/shared/iconify: packages/@core/shared/iconify:
dependencies: dependencies:
'@iconify/vue': '@iconify/vue':
@ -672,6 +656,12 @@ importers:
packages/@core/shared/toolkit: packages/@core/shared/toolkit:
dependencies: dependencies:
'@ant-design/colors':
specifier: ^7.1.0
version: 7.1.0
'@ctrl/tinycolor':
specifier: ^4.1.0
version: 4.1.0
'@vue/shared': '@vue/shared':
specifier: ^3.4.31 specifier: ^3.4.31
version: 3.4.31 version: 3.4.31
@ -757,9 +747,6 @@ importers:
'@radix-icons/vue': '@radix-icons/vue':
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0(vue@3.4.31(typescript@5.5.3)) version: 1.0.0(vue@3.4.31(typescript@5.5.3))
'@vben-core/colorful':
specifier: workspace:*
version: link:../../shared/colorful
'@vben-core/iconify': '@vben-core/iconify':
specifier: workspace:* specifier: workspace:*
version: link:../../shared/iconify version: link:../../shared/iconify
@ -808,9 +795,9 @@ importers:
packages/business/access: packages/business/access:
dependencies: dependencies:
'@vben-core/locales': '@vben-core/helpers':
specifier: workspace:* specifier: workspace:*
version: link:../../@core/locales version: link:../../@core/forward/helpers
'@vben-core/preferences': '@vben-core/preferences':
specifier: workspace:* specifier: workspace:*
version: link:../../@core/forward/preferences version: link:../../@core/forward/preferences
@ -820,16 +807,12 @@ importers:
'@vben-core/toolkit': '@vben-core/toolkit':
specifier: workspace:* specifier: workspace:*
version: link:../../@core/shared/toolkit version: link:../../@core/shared/toolkit
'@vben-core/typings':
specifier: workspace:*
version: link:../../@core/shared/typings
vue: vue:
specifier: ^3.4.31 specifier: ^3.4.31
version: 3.4.31(typescript@5.5.3) version: 3.4.31(typescript@5.5.3)
vue-router:
specifier: ^4.4.0
version: 4.4.0(vue@3.4.31(typescript@5.5.3))
devDependencies:
'@vben/types':
specifier: workspace:*
version: link:../../types
packages/business/chart-ui: packages/business/chart-ui:
dependencies: dependencies:
@ -848,9 +831,6 @@ importers:
packages/business/layouts: packages/business/layouts:
dependencies: dependencies:
'@vben-core/colorful':
specifier: workspace:*
version: link:../../@core/shared/colorful
'@vben-core/helpers': '@vben-core/helpers':
specifier: workspace:* specifier: workspace:*
version: link:../../@core/forward/helpers version: link:../../@core/forward/helpers
@ -881,6 +861,9 @@ importers:
'@vben-core/toolkit': '@vben-core/toolkit':
specifier: workspace:* specifier: workspace:*
version: link:../../@core/shared/toolkit version: link:../../@core/shared/toolkit
'@vben-core/typings':
specifier: workspace:*
version: link:../../@core/shared/typings
'@vueuse/core': '@vueuse/core':
specifier: ^10.11.0 specifier: ^10.11.0
version: 10.11.0(vue@3.4.31(typescript@5.5.3)) version: 10.11.0(vue@3.4.31(typescript@5.5.3))
@ -890,13 +873,6 @@ importers:
vue-router: vue-router:
specifier: ^4.4.0 specifier: ^4.4.0
version: 4.4.0(vue@3.4.31(typescript@5.5.3)) version: 4.4.0(vue@3.4.31(typescript@5.5.3))
devDependencies:
'@vben-core/typings':
specifier: workspace:*
version: link:../../@core/shared/typings
'@vben/types':
specifier: workspace:*
version: link:../../types
packages/business/universal-ui: packages/business/universal-ui:
dependencies: dependencies:
@ -945,9 +921,6 @@ importers:
'@vben-core/design': '@vben-core/design':
specifier: workspace:* specifier: workspace:*
version: link:../@core/shared/design version: link:../@core/shared/design
'@vben-core/design-tokens':
specifier: workspace:*
version: link:../@core/shared/design-tokens
packages/types: packages/types:
dependencies: dependencies:

12
vben-admin.code-workspace

@ -64,22 +64,10 @@
"name": "@vben-core/locales", "name": "@vben-core/locales",
"path": "packages/@core/locales", "path": "packages/@core/locales",
}, },
{
"name": "@vben-core/cache",
"path": "packages/@core/shared/cache",
},
{
"name": "@vben-core/colorful",
"path": "packages/@core/shared/colorful",
},
{ {
"name": "@vben-core/design", "name": "@vben-core/design",
"path": "packages/@core/shared/design", "path": "packages/@core/shared/design",
}, },
{
"name": "@vben-core/design-tokens",
"path": "packages/@core/shared/design-tokens",
},
{ {
"name": "@vben-core/iconify", "name": "@vben-core/iconify",
"path": "packages/@core/shared/iconify", "path": "packages/@core/shared/iconify",

Loading…
Cancel
Save