diff --git a/apps/web-antd/.env b/apps/web-antd/.env deleted file mode 100644 index 19735f36..00000000 --- a/apps/web-antd/.env +++ /dev/null @@ -1,8 +0,0 @@ -# 应用标题 -VITE_APP_TITLE=Vben Admin Antd - -# 应用命名空间,用于缓存、store等功能的前缀,确保隔离 -VITE_APP_NAMESPACE=vben-web-antd - -# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 -VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key diff --git a/apps/web-antd/.env.analyze b/apps/web-antd/.env.analyze deleted file mode 100644 index ffafa8dd..00000000 --- a/apps/web-antd/.env.analyze +++ /dev/null @@ -1,7 +0,0 @@ -# public path -VITE_BASE=/ - -# Basic interface address SPA -VITE_GLOB_API_URL=/api - -VITE_VISUALIZER=true diff --git a/apps/web-antd/.env.development b/apps/web-antd/.env.development deleted file mode 100644 index c138f482..00000000 --- a/apps/web-antd/.env.development +++ /dev/null @@ -1,16 +0,0 @@ -# 端口号 -VITE_PORT=5666 - -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=/api - -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=true - -# 是否打开 devtools,true 为打开,false 为关闭 -VITE_DEVTOOLS=false - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true diff --git a/apps/web-antd/.env.production b/apps/web-antd/.env.production deleted file mode 100644 index 5375847a..00000000 --- a/apps/web-antd/.env.production +++ /dev/null @@ -1,19 +0,0 @@ -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=https://mock-napi.vben.pro/api - -# 是否开启压缩,可以设置为 none, brotli, gzip -VITE_COMPRESS=none - -# 是否开启 PWA -VITE_PWA=false - -# vue-router 的模式 -VITE_ROUTER_HISTORY=hash - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true - -# 打包后是否生成dist.zip -VITE_ARCHIVER=true diff --git a/apps/web-antd/index.html b/apps/web-antd/index.html deleted file mode 100644 index 480eb84d..00000000 --- a/apps/web-antd/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - <%= VITE_APP_TITLE %> - - - - -
- - - diff --git a/apps/web-antd/package.json b/apps/web-antd/package.json deleted file mode 100644 index db7d0070..00000000 --- a/apps/web-antd/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@vben/web-antd", - "version": "5.5.9", - "homepage": "https://vben.pro", - "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", - "repository": { - "type": "git", - "url": "git+https://github.com/vbenjs/vue-vben-admin.git", - "directory": "apps/web-antd" - }, - "license": "MIT", - "author": { - "name": "vben", - "email": "ann.vben@gmail.com", - "url": "https://github.com/anncwb" - }, - "type": "module", - "scripts": { - "build": "pnpm vite build --mode production", - "build:analyze": "pnpm vite build --mode analyze", - "dev": "pnpm vite --mode development", - "preview": "vite preview", - "typecheck": "vue-tsc --noEmit --skipLibCheck" - }, - "imports": { - "#/*": "./src/*" - }, - "dependencies": { - "@vben/access": "workspace:*", - "@vben/common-ui": "workspace:*", - "@vben/constants": "workspace:*", - "@vben/hooks": "workspace:*", - "@vben/icons": "workspace:*", - "@vben/layouts": "workspace:*", - "@vben/locales": "workspace:*", - "@vben/plugins": "workspace:*", - "@vben/preferences": "workspace:*", - "@vben/request": "workspace:*", - "@vben/stores": "workspace:*", - "@vben/styles": "workspace:*", - "@vben/types": "workspace:*", - "@vben/utils": "workspace:*", - "@vueuse/core": "catalog:", - "ant-design-vue": "catalog:", - "dayjs": "catalog:", - "pinia": "catalog:", - "vue": "catalog:", - "vue-router": "catalog:" - } -} diff --git a/apps/web-antd/postcss.config.mjs b/apps/web-antd/postcss.config.mjs deleted file mode 100644 index 3d807045..00000000 --- a/apps/web-antd/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-antd/public/favicon.ico b/apps/web-antd/public/favicon.ico deleted file mode 100644 index fcf9818e..00000000 Binary files a/apps/web-antd/public/favicon.ico and /dev/null differ diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts deleted file mode 100644 index 786a93da..00000000 --- a/apps/web-antd/src/adapter/component/index.ts +++ /dev/null @@ -1,211 +0,0 @@ -/** - * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用 - * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, - */ - -import type { Component } from 'vue'; - -import type { BaseFormComponentType } from '@vben/common-ui'; -import type { Recordable } from '@vben/types'; - -import { defineAsyncComponent, defineComponent, h, ref } from 'vue'; - -import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -import { notification } from 'ant-design-vue'; - -const AutoComplete = defineAsyncComponent( - () => import('ant-design-vue/es/auto-complete'), -); -const Button = defineAsyncComponent(() => import('ant-design-vue/es/button')); -const Checkbox = defineAsyncComponent( - () => import('ant-design-vue/es/checkbox'), -); -const CheckboxGroup = defineAsyncComponent(() => - import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup), -); -const DatePicker = defineAsyncComponent( - () => import('ant-design-vue/es/date-picker'), -); -const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider')); -const Input = defineAsyncComponent(() => import('ant-design-vue/es/input')); -const InputNumber = defineAsyncComponent( - () => import('ant-design-vue/es/input-number'), -); -const InputPassword = defineAsyncComponent(() => - import('ant-design-vue/es/input').then((res) => res.InputPassword), -); -const Mentions = defineAsyncComponent( - () => import('ant-design-vue/es/mentions'), -); -const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio')); -const RadioGroup = defineAsyncComponent(() => - import('ant-design-vue/es/radio').then((res) => res.RadioGroup), -); -const RangePicker = defineAsyncComponent(() => - import('ant-design-vue/es/date-picker').then((res) => res.RangePicker), -); -const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate')); -const Select = defineAsyncComponent(() => import('ant-design-vue/es/select')); -const Space = defineAsyncComponent(() => import('ant-design-vue/es/space')); -const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch')); -const Textarea = defineAsyncComponent(() => - import('ant-design-vue/es/input').then((res) => res.Textarea), -); -const TimePicker = defineAsyncComponent( - () => import('ant-design-vue/es/time-picker'), -); -const TreeSelect = defineAsyncComponent( - () => import('ant-design-vue/es/tree-select'), -); -const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); - -const withDefaultPlaceholder = ( - component: T, - type: 'input' | 'select', - componentProps: Recordable = {}, -) => { - return defineComponent({ - name: component.name, - inheritAttrs: false, - setup: (props: any, { attrs, expose, slots }) => { - const placeholder = - props?.placeholder || - attrs?.placeholder || - $t(`ui.placeholder.${type}`); - // 透传组件暴露的方法 - const innerRef = ref(); - expose( - new Proxy( - {}, - { - get: (_target, key) => innerRef.value?.[key], - has: (_target, key) => key in (innerRef.value || {}), - }, - ), - ); - return () => - h( - component, - { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, - slots, - ); - }, - }); -}; - -// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 -export type ComponentType = - | 'ApiSelect' - | 'ApiTreeSelect' - | 'AutoComplete' - | 'Checkbox' - | 'CheckboxGroup' - | 'DatePicker' - | 'DefaultButton' - | 'Divider' - | 'IconPicker' - | 'Input' - | 'InputNumber' - | 'InputPassword' - | 'Mentions' - | 'PrimaryButton' - | 'Radio' - | 'RadioGroup' - | 'RangePicker' - | 'Rate' - | 'Select' - | 'Space' - | 'Switch' - | 'Textarea' - | 'TimePicker' - | 'TreeSelect' - | 'Upload' - | BaseFormComponentType; - -async function initComponentAdapter() { - const components: Partial> = { - // 如果你的组件体积比较大,可以使用异步加载 - // Button: () => - // import('xxx').then((res) => res.Button), - ApiSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiSelect', - }, - 'select', - { - component: Select, - loadingSlot: 'suffixIcon', - visibleEvent: 'onDropdownVisibleChange', - modelPropName: 'value', - }, - ), - ApiTreeSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiTreeSelect', - }, - 'select', - { - component: TreeSelect, - fieldNames: { label: 'label', value: 'value', children: 'children' }, - loadingSlot: 'suffixIcon', - modelPropName: 'value', - optionsPropName: 'treeData', - visibleEvent: 'onVisibleChange', - }, - ), - AutoComplete, - Checkbox, - CheckboxGroup, - DatePicker, - // 自定义默认按钮 - DefaultButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: 'default' }, slots); - }, - Divider, - IconPicker: withDefaultPlaceholder(IconPicker, 'select', { - iconSlot: 'addonAfter', - inputComponent: Input, - modelValueProp: 'value', - }), - Input: withDefaultPlaceholder(Input, 'input'), - InputNumber: withDefaultPlaceholder(InputNumber, 'input'), - InputPassword: withDefaultPlaceholder(InputPassword, 'input'), - Mentions: withDefaultPlaceholder(Mentions, 'input'), - // 自定义主要按钮 - PrimaryButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, type: 'primary' }, slots); - }, - Radio, - RadioGroup, - RangePicker, - Rate, - Select: withDefaultPlaceholder(Select, 'select'), - Space, - Switch, - Textarea: withDefaultPlaceholder(Textarea, 'input'), - TimePicker, - TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), - Upload, - }; - - // 将组件注册到全局共享状态中 - globalShareState.setComponents(components); - - // 定义全局共享状态中的消息提示 - globalShareState.defineMessage({ - // 复制成功消息提示 - copyPreferencesSuccess: (title, content) => { - notification.success({ - description: content, - message: title, - placement: 'bottomRight', - }); - }, - }); -} - -export { initComponentAdapter }; diff --git a/apps/web-antd/src/adapter/form.ts b/apps/web-antd/src/adapter/form.ts deleted file mode 100644 index 983a7f51..00000000 --- a/apps/web-antd/src/adapter/form.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { - VbenFormSchema as FormSchema, - VbenFormProps, -} from '@vben/common-ui'; - -import type { ComponentType } from './component'; - -import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -async function initSetupVbenForm() { - setupVbenForm({ - config: { - // ant design vue组件库默认都是 v-model:value - baseModelPropName: 'value', - - // 一些组件是 v-model:checked 或者 v-model:fileList - modelPropNameMap: { - Checkbox: 'checked', - Radio: 'checked', - Switch: 'checked', - Upload: 'fileList', - }, - }, - defineRules: { - // 输入项目必填国际化适配 - required: (value, _params, ctx) => { - if (value === undefined || value === null || value.length === 0) { - return $t('ui.formRules.required', [ctx.label]); - } - return true; - }, - // 选择项目必填国际化适配 - selectRequired: (value, _params, ctx) => { - if (value === undefined || value === null) { - return $t('ui.formRules.selectRequired', [ctx.label]); - } - return true; - }, - }, - }); -} - -const useVbenForm = useForm; - -export { initSetupVbenForm, useVbenForm, z }; - -export type VbenFormSchema = FormSchema; -export type { VbenFormProps }; diff --git a/apps/web-antd/src/adapter/vxe-table.ts b/apps/web-antd/src/adapter/vxe-table.ts deleted file mode 100644 index 7de2859d..00000000 --- a/apps/web-antd/src/adapter/vxe-table.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { VxeTableGridOptions } from '@vben/plugins/vxe-table'; - -import { h } from 'vue'; - -import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; - -import { Button, Image } from 'ant-design-vue'; - -import { useVbenForm } from './form'; - -setupVbenVxeTable({ - configVxeTable: (vxeUI) => { - vxeUI.setConfig({ - grid: { - align: 'center', - border: false, - columnConfig: { - resizable: true, - }, - minHeight: 180, - formConfig: { - // 全局禁用vxe-table的表单配置,使用formOptions - enabled: false, - }, - proxyConfig: { - autoLoad: true, - response: { - result: 'items', - total: 'total', - list: 'items', - }, - showActiveMsg: true, - showResponseMsg: false, - }, - round: true, - showOverflow: true, - size: 'small', - } as VxeTableGridOptions, - }); - - // 表格配置项可以用 cellRender: { name: 'CellImage' }, - vxeUI.renderer.add('CellImage', { - renderTableDefault(_renderOpts, params) { - const { column, row } = params; - return h(Image, { src: row[column.field] }); - }, - }); - - // 表格配置项可以用 cellRender: { name: 'CellLink' }, - vxeUI.renderer.add('CellLink', { - renderTableDefault(renderOpts) { - const { props } = renderOpts; - return h( - Button, - { size: 'small', type: 'link' }, - { default: () => props?.text }, - ); - }, - }); - - // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 - // vxeUI.formats.add - }, - useVbenForm, -}); - -export { useVbenVxeGrid }; - -export type * from '@vben/plugins/vxe-table'; diff --git a/apps/web-antd/src/api/core/auth.ts b/apps/web-antd/src/api/core/auth.ts deleted file mode 100644 index 71d9f994..00000000 --- a/apps/web-antd/src/api/core/auth.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { baseRequestClient, requestClient } from '#/api/request'; - -export namespace AuthApi { - /** 登录接口参数 */ - export interface LoginParams { - password?: string; - username?: string; - } - - /** 登录接口返回值 */ - export interface LoginResult { - accessToken: string; - } - - export interface RefreshTokenResult { - data: string; - status: number; - } -} - -/** - * 登录 - */ -export async function loginApi(data: AuthApi.LoginParams) { - return requestClient.post('/auth/login', data); -} - -/** - * 刷新accessToken - */ -export async function refreshTokenApi() { - return baseRequestClient.post('/auth/refresh', { - withCredentials: true, - }); -} - -/** - * 退出登录 - */ -export async function logoutApi() { - return baseRequestClient.post('/auth/logout', { - withCredentials: true, - }); -} - -/** - * 获取用户权限码 - */ -export async function getAccessCodesApi() { - return requestClient.get('/auth/codes'); -} diff --git a/apps/web-antd/src/api/core/index.ts b/apps/web-antd/src/api/core/index.ts deleted file mode 100644 index 28a5aef4..00000000 --- a/apps/web-antd/src/api/core/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './auth'; -export * from './menu'; -export * from './user'; diff --git a/apps/web-antd/src/api/core/menu.ts b/apps/web-antd/src/api/core/menu.ts deleted file mode 100644 index 9ef60b11..00000000 --- a/apps/web-antd/src/api/core/menu.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { RouteRecordStringComponent } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户所有菜单 - */ -export async function getAllMenusApi() { - return requestClient.get('/menu/all'); -} diff --git a/apps/web-antd/src/api/core/user.ts b/apps/web-antd/src/api/core/user.ts deleted file mode 100644 index 7e28ea84..00000000 --- a/apps/web-antd/src/api/core/user.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UserInfo } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户信息 - */ -export async function getUserInfoApi() { - return requestClient.get('/user/info'); -} diff --git a/apps/web-antd/src/api/index.ts b/apps/web-antd/src/api/index.ts deleted file mode 100644 index 4b0e0413..00000000 --- a/apps/web-antd/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './core'; diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts deleted file mode 100644 index 288dddd0..00000000 --- a/apps/web-antd/src/api/request.ts +++ /dev/null @@ -1,113 +0,0 @@ -/** - * 该文件可自行根据业务逻辑进行调整 - */ -import type { RequestClientOptions } from '@vben/request'; - -import { useAppConfig } from '@vben/hooks'; -import { preferences } from '@vben/preferences'; -import { - authenticateResponseInterceptor, - defaultResponseInterceptor, - errorMessageResponseInterceptor, - RequestClient, -} from '@vben/request'; -import { useAccessStore } from '@vben/stores'; - -import { message } from 'ant-design-vue'; - -import { useAuthStore } from '#/store'; - -import { refreshTokenApi } from './core'; - -const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); - -function createRequestClient(baseURL: string, options?: RequestClientOptions) { - const client = new RequestClient({ - ...options, - baseURL, - }); - - /** - * 重新认证逻辑 - */ - async function doReAuthenticate() { - console.warn('Access token or refresh token is invalid or expired. '); - const accessStore = useAccessStore(); - const authStore = useAuthStore(); - accessStore.setAccessToken(null); - if ( - preferences.app.loginExpiredMode === 'modal' && - accessStore.isAccessChecked - ) { - accessStore.setLoginExpired(true); - } else { - await authStore.logout(); - } - } - - /** - * 刷新token逻辑 - */ - async function doRefreshToken() { - const accessStore = useAccessStore(); - const resp = await refreshTokenApi(); - const newToken = resp.data; - accessStore.setAccessToken(newToken); - return newToken; - } - - function formatToken(token: null | string) { - return token ? `Bearer ${token}` : null; - } - - // 请求头处理 - client.addRequestInterceptor({ - fulfilled: async (config) => { - const accessStore = useAccessStore(); - - config.headers.Authorization = formatToken(accessStore.accessToken); - config.headers['Accept-Language'] = preferences.app.locale; - return config; - }, - }); - - // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); - - // token过期的处理 - client.addResponseInterceptor( - authenticateResponseInterceptor({ - client, - doReAuthenticate, - doRefreshToken, - enableRefreshToken: preferences.app.enableRefreshToken, - formatToken, - }), - ); - - // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里 - client.addResponseInterceptor( - errorMessageResponseInterceptor((msg: string, error) => { - // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg - // 当前mock接口返回的错误字段是 error 或者 message - const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; - // 如果没有错误信息,则会根据状态码进行提示 - message.error(errorMessage || msg); - }), - ); - - return client; -} - -export const requestClient = createRequestClient(apiURL, { - responseReturn: 'data', -}); - -export const baseRequestClient = new RequestClient({ baseURL: apiURL }); diff --git a/apps/web-antd/src/app.vue b/apps/web-antd/src/app.vue deleted file mode 100644 index bbaccce1..00000000 --- a/apps/web-antd/src/app.vue +++ /dev/null @@ -1,39 +0,0 @@ - - - diff --git a/apps/web-antd/src/bootstrap.ts b/apps/web-antd/src/bootstrap.ts deleted file mode 100644 index ec721125..00000000 --- a/apps/web-antd/src/bootstrap.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { createApp, watchEffect } from 'vue'; - -import { registerAccessDirective } from '@vben/access'; -import { registerLoadingDirective } from '@vben/common-ui/es/loading'; -import { preferences } from '@vben/preferences'; -import { initStores } from '@vben/stores'; -import '@vben/styles'; -import '@vben/styles/antd'; - -import { useTitle } from '@vueuse/core'; - -import { $t, setupI18n } from '#/locales'; - -import { initComponentAdapter } from './adapter/component'; -import { initSetupVbenForm } from './adapter/form'; -import App from './app.vue'; -import { router } from './router'; - -async function bootstrap(namespace: string) { - // 初始化组件适配器 - await initComponentAdapter(); - - // 初始化表单组件 - await initSetupVbenForm(); - - // // 设置弹窗的默认配置 - // setDefaultModalProps({ - // fullscreenButton: false, - // }); - // // 设置抽屉的默认配置 - // setDefaultDrawerProps({ - // zIndex: 1020, - // }); - - const app = createApp(App); - - // 注册v-loading指令 - registerLoadingDirective(app, { - loading: 'loading', // 在这里可以自定义指令名称,也可以明确提供false表示不注册这个指令 - spinning: 'spinning', - }); - - // 国际化 i18n 配置 - await setupI18n(app); - - // 配置 pinia-tore - await initStores(app, { namespace }); - - // 安装权限指令 - registerAccessDirective(app); - - // 初始化 tippy - const { initTippy } = await import('@vben/common-ui/es/tippy'); - initTippy(app); - - // 配置路由及路由守卫 - app.use(router); - - // 配置Motion插件 - const { MotionPlugin } = await import('@vben/plugins/motion'); - app.use(MotionPlugin); - - // 动态更新标题 - watchEffect(() => { - if (preferences.app.dynamicTitle) { - const routeTitle = router.currentRoute.value.meta?.title; - const pageTitle = - (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; - useTitle(pageTitle); - } - }); - - app.mount('#app'); -} - -export { bootstrap }; diff --git a/apps/web-antd/src/layouts/auth.vue b/apps/web-antd/src/layouts/auth.vue deleted file mode 100644 index 8ba66e85..00000000 --- a/apps/web-antd/src/layouts/auth.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/apps/web-antd/src/layouts/basic.vue b/apps/web-antd/src/layouts/basic.vue deleted file mode 100644 index 2226c68a..00000000 --- a/apps/web-antd/src/layouts/basic.vue +++ /dev/null @@ -1,206 +0,0 @@ - - - diff --git a/apps/web-antd/src/layouts/index.ts b/apps/web-antd/src/layouts/index.ts deleted file mode 100644 index a4320780..00000000 --- a/apps/web-antd/src/layouts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -const BasicLayout = () => import('./basic.vue'); -const AuthPageLayout = () => import('./auth.vue'); - -const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView); - -export { AuthPageLayout, BasicLayout, IFrameView }; diff --git a/apps/web-antd/src/locales/README.md b/apps/web-antd/src/locales/README.md deleted file mode 100644 index 7b451032..00000000 --- a/apps/web-antd/src/locales/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# locale - -每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。 diff --git a/apps/web-antd/src/locales/index.ts b/apps/web-antd/src/locales/index.ts deleted file mode 100644 index 7f32bd18..00000000 --- a/apps/web-antd/src/locales/index.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { Locale } from 'ant-design-vue/es/locale'; - -import type { App } from 'vue'; - -import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales'; - -import { ref } from 'vue'; - -import { - $t, - setupI18n as coreSetup, - loadLocalesMapFromDir, -} from '@vben/locales'; -import { preferences } from '@vben/preferences'; - -import antdEnLocale from 'ant-design-vue/es/locale/en_US'; -import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN'; -import dayjs from 'dayjs'; - -const antdLocale = ref(antdDefaultLocale); - -const modules = import.meta.glob('./langs/**/*.json'); - -const localesMap = loadLocalesMapFromDir( - /\.\/langs\/([^/]+)\/(.*)\.json$/, - modules, -); -/** - * 加载应用特有的语言包 - * 这里也可以改造为从服务端获取翻译数据 - * @param lang - */ -async function loadMessages(lang: SupportedLanguagesType) { - const [appLocaleMessages] = await Promise.all([ - localesMap[lang]?.(), - loadThirdPartyMessage(lang), - ]); - return appLocaleMessages?.default; -} - -/** - * 加载第三方组件库的语言包 - * @param lang - */ -async function loadThirdPartyMessage(lang: SupportedLanguagesType) { - await Promise.all([loadAntdLocale(lang), loadDayjsLocale(lang)]); -} - -/** - * 加载dayjs的语言包 - * @param lang - */ -async function loadDayjsLocale(lang: SupportedLanguagesType) { - let locale; - switch (lang) { - case 'en-US': { - locale = await import('dayjs/locale/en'); - break; - } - case 'zh-CN': { - locale = await import('dayjs/locale/zh-cn'); - break; - } - // 默认使用英语 - default: { - locale = await import('dayjs/locale/en'); - } - } - if (locale) { - dayjs.locale(locale); - } else { - console.error(`Failed to load dayjs locale for ${lang}`); - } -} - -/** - * 加载antd的语言包 - * @param lang - */ -async function loadAntdLocale(lang: SupportedLanguagesType) { - switch (lang) { - case 'en-US': { - antdLocale.value = antdEnLocale; - break; - } - case 'zh-CN': { - antdLocale.value = antdDefaultLocale; - break; - } - } -} - -async function setupI18n(app: App, options: LocaleSetupOptions = {}) { - await coreSetup(app, { - defaultLocale: preferences.app.locale, - loadMessages, - missingWarn: !import.meta.env.PROD, - ...options, - }); -} - -export { $t, antdLocale, setupI18n }; diff --git a/apps/web-antd/src/locales/langs/en-US/demos.json b/apps/web-antd/src/locales/langs/en-US/demos.json deleted file mode 100644 index 12a3b718..00000000 --- a/apps/web-antd/src/locales/langs/en-US/demos.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "title": "Demos", - "antd": "Ant Design Vue", - "vben": { - "title": "Project", - "about": "About", - "document": "Document", - "antdv": "Ant Design Vue Version", - "naive-ui": "Naive UI Version", - "element-plus": "Element Plus Version", - "tdesign": "TDesign Vue Version" - } -} diff --git a/apps/web-antd/src/locales/langs/en-US/page.json b/apps/web-antd/src/locales/langs/en-US/page.json deleted file mode 100644 index 39f1641c..00000000 --- a/apps/web-antd/src/locales/langs/en-US/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "Login", - "register": "Register", - "codeLogin": "Code Login", - "qrcodeLogin": "Qr Code Login", - "forgetPassword": "Forget Password", - "profile": "Profile" - }, - "dashboard": { - "title": "Dashboard", - "analytics": "Analytics", - "workspace": "Workspace" - } -} diff --git a/apps/web-antd/src/locales/langs/zh-CN/demos.json b/apps/web-antd/src/locales/langs/zh-CN/demos.json deleted file mode 100644 index b5007ea7..00000000 --- a/apps/web-antd/src/locales/langs/zh-CN/demos.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "title": "演示", - "antd": "Ant Design Vue", - "vben": { - "title": "项目", - "about": "关于", - "document": "文档", - "antdv": "Ant Design Vue 版本", - "naive-ui": "Naive UI 版本", - "element-plus": "Element Plus 版本", - "tdesign": "TDesign Vue 版本" - } -} diff --git a/apps/web-antd/src/locales/langs/zh-CN/page.json b/apps/web-antd/src/locales/langs/zh-CN/page.json deleted file mode 100644 index 2192d1d5..00000000 --- a/apps/web-antd/src/locales/langs/zh-CN/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "登录", - "register": "注册", - "codeLogin": "验证码登录", - "qrcodeLogin": "二维码登录", - "forgetPassword": "忘记密码", - "profile": "个人中心" - }, - "dashboard": { - "title": "概览", - "analytics": "分析页", - "workspace": "工作台" - } -} diff --git a/apps/web-antd/src/main.ts b/apps/web-antd/src/main.ts deleted file mode 100644 index 5d728a02..00000000 --- a/apps/web-antd/src/main.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { initPreferences } from '@vben/preferences'; -import { unmountGlobalLoading } from '@vben/utils'; - -import { overridesPreferences } from './preferences'; - -/** - * 应用初始化完成之后再进行页面加载渲染 - */ -async function initApplication() { - // name用于指定项目唯一标识 - // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据 - const env = import.meta.env.PROD ? 'prod' : 'dev'; - const appVersion = import.meta.env.VITE_APP_VERSION; - const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`; - - // app偏好设置初始化 - await initPreferences({ - namespace, - overrides: overridesPreferences, - }); - - // 启动应用并挂载 - // vue应用主要逻辑及视图 - const { bootstrap } = await import('./bootstrap'); - await bootstrap(namespace); - - // 移除并销毁loading - unmountGlobalLoading(); -} - -initApplication(); diff --git a/apps/web-antd/src/preferences.ts b/apps/web-antd/src/preferences.ts deleted file mode 100644 index b2e9ace4..00000000 --- a/apps/web-antd/src/preferences.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineOverridesPreferences } from '@vben/preferences'; - -/** - * @description 项目配置文件 - * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 - * !!! 更改配置后请清空缓存,否则可能不生效 - */ -export const overridesPreferences = defineOverridesPreferences({ - // overrides - app: { - name: import.meta.env.VITE_APP_TITLE, - }, -}); diff --git a/apps/web-antd/src/router/access.ts b/apps/web-antd/src/router/access.ts deleted file mode 100644 index 3a48be23..00000000 --- a/apps/web-antd/src/router/access.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { - ComponentRecordType, - GenerateMenuAndRoutesOptions, -} from '@vben/types'; - -import { generateAccessible } from '@vben/access'; -import { preferences } from '@vben/preferences'; - -import { message } from 'ant-design-vue'; - -import { getAllMenusApi } from '#/api'; -import { BasicLayout, IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue'); - -async function generateAccess(options: GenerateMenuAndRoutesOptions) { - const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); - - const layoutMap: ComponentRecordType = { - BasicLayout, - IFrameView, - }; - - return await generateAccessible(preferences.app.accessMode, { - ...options, - fetchMenuListAsync: async () => { - message.loading({ - content: `${$t('common.loadingMenu')}...`, - duration: 1.5, - }); - return await getAllMenusApi(); - }, - // 可以指定没有权限跳转403页面 - forbiddenComponent, - // 如果 route.meta.menuVisibleWithForbidden = true - layoutMap, - pageMap, - }); -} - -export { generateAccess }; diff --git a/apps/web-antd/src/router/guard.ts b/apps/web-antd/src/router/guard.ts deleted file mode 100644 index a1ad6d88..00000000 --- a/apps/web-antd/src/router/guard.ts +++ /dev/null @@ -1,133 +0,0 @@ -import type { Router } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { useAccessStore, useUserStore } from '@vben/stores'; -import { startProgress, stopProgress } from '@vben/utils'; - -import { accessRoutes, coreRouteNames } from '#/router/routes'; -import { useAuthStore } from '#/store'; - -import { generateAccess } from './access'; - -/** - * 通用守卫配置 - * @param router - */ -function setupCommonGuard(router: Router) { - // 记录已经加载的页面 - const loadedPaths = new Set(); - - router.beforeEach((to) => { - to.meta.loaded = loadedPaths.has(to.path); - - // 页面加载进度条 - if (!to.meta.loaded && preferences.transition.progress) { - startProgress(); - } - return true; - }); - - router.afterEach((to) => { - // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行 - - loadedPaths.add(to.path); - - // 关闭页面加载进度条 - if (preferences.transition.progress) { - stopProgress(); - } - }); -} - -/** - * 权限访问守卫配置 - * @param router - */ -function setupAccessGuard(router: Router) { - router.beforeEach(async (to, from) => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const authStore = useAuthStore(); - - // 基本路由,这些路由不需要进入权限拦截 - if (coreRouteNames.includes(to.name as string)) { - if (to.path === LOGIN_PATH && accessStore.accessToken) { - return decodeURIComponent( - (to.query?.redirect as string) || - userStore.userInfo?.homePath || - preferences.app.defaultHomePath, - ); - } - return true; - } - - // accessToken 检查 - if (!accessStore.accessToken) { - // 明确声明忽略权限访问权限,则可以访问 - if (to.meta.ignoreAccess) { - return true; - } - - // 没有访问权限,跳转登录页面 - if (to.fullPath !== LOGIN_PATH) { - return { - path: LOGIN_PATH, - // 如不需要,直接删除 query - query: - to.fullPath === preferences.app.defaultHomePath - ? {} - : { redirect: encodeURIComponent(to.fullPath) }, - // 携带当前跳转的页面,登录后重新跳转该页面 - replace: true, - }; - } - return to; - } - - // 是否已经生成过动态路由 - if (accessStore.isAccessChecked) { - return true; - } - - // 生成路由表 - // 当前登录用户拥有的角色标识列表 - const userInfo = userStore.userInfo || (await authStore.fetchUserInfo()); - const userRoles = userInfo.roles ?? []; - - // 生成菜单和路由 - const { accessibleMenus, accessibleRoutes } = await generateAccess({ - roles: userRoles, - router, - // 则会在菜单中显示,但是访问会被重定向到403 - routes: accessRoutes, - }); - - // 保存菜单信息和路由信息 - accessStore.setAccessMenus(accessibleMenus); - accessStore.setAccessRoutes(accessibleRoutes); - accessStore.setIsAccessChecked(true); - const redirectPath = (from.query.redirect ?? - (to.path === preferences.app.defaultHomePath - ? userInfo.homePath || preferences.app.defaultHomePath - : to.fullPath)) as string; - - return { - ...router.resolve(decodeURIComponent(redirectPath)), - replace: true, - }; - }); -} - -/** - * 项目守卫配置 - * @param router - */ -function createRouterGuard(router: Router) { - /** 通用 */ - setupCommonGuard(router); - /** 权限访问 */ - setupAccessGuard(router); -} - -export { createRouterGuard }; diff --git a/apps/web-antd/src/router/index.ts b/apps/web-antd/src/router/index.ts deleted file mode 100644 index 48402303..00000000 --- a/apps/web-antd/src/router/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - createRouter, - createWebHashHistory, - createWebHistory, -} from 'vue-router'; - -import { resetStaticRoutes } from '@vben/utils'; - -import { createRouterGuard } from './guard'; -import { routes } from './routes'; - -/** - * @zh_CN 创建vue-router实例 - */ -const router = createRouter({ - history: - import.meta.env.VITE_ROUTER_HISTORY === 'hash' - ? createWebHashHistory(import.meta.env.VITE_BASE) - : createWebHistory(import.meta.env.VITE_BASE), - // 应该添加到路由的初始路由列表。 - routes, - scrollBehavior: (to, _from, savedPosition) => { - if (savedPosition) { - return savedPosition; - } - return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; - }, - // 是否应该禁止尾部斜杠。 - // strict: true, -}); - -const resetRoutes = () => resetStaticRoutes(router, routes); - -// 创建路由守卫 -createRouterGuard(router); - -export { resetRoutes, router }; diff --git a/apps/web-antd/src/router/routes/core.ts b/apps/web-antd/src/router/routes/core.ts deleted file mode 100644 index 949b0b65..00000000 --- a/apps/web-antd/src/router/routes/core.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; - -import { $t } from '#/locales'; - -const BasicLayout = () => import('#/layouts/basic.vue'); -const AuthPageLayout = () => import('#/layouts/auth.vue'); -/** 全局404页面 */ -const fallbackNotFoundRoute: RouteRecordRaw = { - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - hideInBreadcrumb: true, - hideInMenu: true, - hideInTab: true, - title: '404', - }, - name: 'FallbackNotFound', - path: '/:path(.*)*', -}; - -/** 基本路由,这些路由是必须存在的 */ -const coreRoutes: RouteRecordRaw[] = [ - /** - * 根路由 - * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 - * 此路由必须存在,且不应修改 - */ - { - component: BasicLayout, - meta: { - hideInBreadcrumb: true, - title: 'Root', - }, - name: 'Root', - path: '/', - redirect: preferences.app.defaultHomePath, - children: [], - }, - { - component: AuthPageLayout, - meta: { - hideInTab: true, - title: 'Authentication', - }, - name: 'Authentication', - path: '/auth', - redirect: LOGIN_PATH, - children: [ - { - name: 'Login', - path: 'login', - component: () => import('#/views/_core/authentication/login.vue'), - meta: { - title: $t('page.auth.login'), - }, - }, - { - name: 'CodeLogin', - path: 'code-login', - component: () => import('#/views/_core/authentication/code-login.vue'), - meta: { - title: $t('page.auth.codeLogin'), - }, - }, - { - name: 'QrCodeLogin', - path: 'qrcode-login', - component: () => - import('#/views/_core/authentication/qrcode-login.vue'), - meta: { - title: $t('page.auth.qrcodeLogin'), - }, - }, - { - name: 'ForgetPassword', - path: 'forget-password', - component: () => - import('#/views/_core/authentication/forget-password.vue'), - meta: { - title: $t('page.auth.forgetPassword'), - }, - }, - { - name: 'Register', - path: 'register', - component: () => import('#/views/_core/authentication/register.vue'), - meta: { - title: $t('page.auth.register'), - }, - }, - ], - }, -]; - -export { coreRoutes, fallbackNotFoundRoute }; diff --git a/apps/web-antd/src/router/routes/index.ts b/apps/web-antd/src/router/routes/index.ts deleted file mode 100644 index e6fb1440..00000000 --- a/apps/web-antd/src/router/routes/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { mergeRouteModules, traverseTreeValues } from '@vben/utils'; - -import { coreRoutes, fallbackNotFoundRoute } from './core'; - -const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { - eager: true, -}); - -// 有需要可以自行打开注释,并创建文件夹 -// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true }); -// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true }); - -/** 动态路由 */ -const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); - -/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ -// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); -// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); -const staticRoutes: RouteRecordRaw[] = []; -const externalRoutes: RouteRecordRaw[] = []; - -/** 路由列表,由基本路由、外部路由和404兜底路由组成 - * 无需走权限验证(会一直显示在菜单中) */ -const routes: RouteRecordRaw[] = [ - ...coreRoutes, - ...externalRoutes, - fallbackNotFoundRoute, -]; - -/** 基本路由列表,这些路由不需要进入权限拦截 */ -const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); - -/** 有权限校验的路由列表,包含动态路由和静态路由 */ -const accessRoutes = [...dynamicRoutes, ...staticRoutes]; -export { accessRoutes, coreRouteNames, routes }; diff --git a/apps/web-antd/src/router/routes/modules/dashboard.ts b/apps/web-antd/src/router/routes/modules/dashboard.ts deleted file mode 100644 index 5254dc65..00000000 --- a/apps/web-antd/src/router/routes/modules/dashboard.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'lucide:layout-dashboard', - order: -1, - title: $t('page.dashboard.title'), - }, - name: 'Dashboard', - path: '/dashboard', - children: [ - { - name: 'Analytics', - path: '/analytics', - component: () => import('#/views/dashboard/analytics/index.vue'), - meta: { - affixTab: true, - icon: 'lucide:area-chart', - title: $t('page.dashboard.analytics'), - }, - }, - { - name: 'Workspace', - path: '/workspace', - component: () => import('#/views/dashboard/workspace/index.vue'), - meta: { - icon: 'carbon:workspace', - title: $t('page.dashboard.workspace'), - }, - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-antd/src/router/routes/modules/demos.ts b/apps/web-antd/src/router/routes/modules/demos.ts deleted file mode 100644 index 55ade09c..00000000 --- a/apps/web-antd/src/router/routes/modules/demos.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ic:baseline-view-in-ar', - keepAlive: true, - order: 1000, - title: $t('demos.title'), - }, - name: 'Demos', - path: '/demos', - children: [ - { - meta: { - title: $t('demos.antd'), - }, - name: 'AntDesignDemos', - path: '/demos/ant-design', - component: () => import('#/views/demos/antd/index.vue'), - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-antd/src/router/routes/modules/vben.ts b/apps/web-antd/src/router/routes/modules/vben.ts deleted file mode 100644 index 631facc0..00000000 --- a/apps/web-antd/src/router/routes/modules/vben.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { - VBEN_DOC_URL, - VBEN_ELE_PREVIEW_URL, - VBEN_GITHUB_URL, - VBEN_LOGO_URL, - VBEN_NAIVE_PREVIEW_URL, - VBEN_TD_PREVIEW_URL, -} from '@vben/constants'; -import { SvgTDesignIcon } from '@vben/icons'; - -import { IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - badgeType: 'dot', - icon: VBEN_LOGO_URL, - order: 9998, - title: $t('demos.vben.title'), - }, - name: 'VbenProject', - path: '/vben-admin', - children: [ - { - name: 'VbenDocument', - path: '/vben-admin/document', - component: IFrameView, - meta: { - icon: 'lucide:book-open-text', - link: VBEN_DOC_URL, - title: $t('demos.vben.document'), - }, - }, - { - name: 'VbenGithub', - path: '/vben-admin/github', - component: IFrameView, - meta: { - icon: 'mdi:github', - link: VBEN_GITHUB_URL, - title: 'Github', - }, - }, - { - name: 'VbenNaive', - path: '/vben-admin/naive', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:naiveui', - link: VBEN_NAIVE_PREVIEW_URL, - title: $t('demos.vben.naive-ui'), - }, - }, - { - name: 'VbenTDesign', - path: '/vben-admin/tdesign', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgTDesignIcon, - link: VBEN_TD_PREVIEW_URL, - title: $t('demos.vben.tdesign'), - }, - }, - { - name: 'VbenElementPlus', - path: '/vben-admin/ele', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:element', - link: VBEN_ELE_PREVIEW_URL, - title: $t('demos.vben.element-plus'), - }, - }, - ], - }, - { - name: 'VbenAbout', - path: '/vben-admin/about', - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - title: $t('demos.vben.about'), - order: 9999, - }, - }, - { - name: 'Profile', - path: '/profile', - component: () => import('#/views/_core/profile/index.vue'), - meta: { - icon: 'lucide:user', - hideInMenu: true, - title: $t('page.auth.profile'), - }, - }, -]; - -export default routes; diff --git a/apps/web-antd/src/store/auth.ts b/apps/web-antd/src/store/auth.ts deleted file mode 100644 index bd496d1e..00000000 --- a/apps/web-antd/src/store/auth.ts +++ /dev/null @@ -1,118 +0,0 @@ -import type { Recordable, UserInfo } from '@vben/types'; - -import { ref } from 'vue'; -import { useRouter } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; - -import { notification } from 'ant-design-vue'; -import { defineStore } from 'pinia'; - -import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api'; -import { $t } from '#/locales'; - -export const useAuthStore = defineStore('auth', () => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const router = useRouter(); - - const loginLoading = ref(false); - - /** - * 异步处理登录操作 - * Asynchronously handle the login process - * @param params 登录表单数据 - */ - async function authLogin( - params: Recordable, - onSuccess?: () => Promise | void, - ) { - // 异步处理用户登录操作并获取 accessToken - let userInfo: null | UserInfo = null; - try { - loginLoading.value = true; - const { accessToken } = await loginApi(params); - - // 如果成功获取到 accessToken - if (accessToken) { - accessStore.setAccessToken(accessToken); - - // 获取用户信息并存储到 accessStore 中 - const [fetchUserInfoResult, accessCodes] = await Promise.all([ - fetchUserInfo(), - getAccessCodesApi(), - ]); - - userInfo = fetchUserInfoResult; - - userStore.setUserInfo(userInfo); - accessStore.setAccessCodes(accessCodes); - - if (accessStore.loginExpired) { - accessStore.setLoginExpired(false); - } else { - onSuccess - ? await onSuccess?.() - : await router.push( - userInfo.homePath || preferences.app.defaultHomePath, - ); - } - - if (userInfo?.realName) { - notification.success({ - description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, - duration: 3, - message: $t('authentication.loginSuccess'), - }); - } - } - } finally { - loginLoading.value = false; - } - - return { - userInfo, - }; - } - - async function logout(redirect: boolean = true) { - try { - await logoutApi(); - } catch { - // 不做任何处理 - } - resetAllStores(); - accessStore.setLoginExpired(false); - - // 回登录页带上当前路由地址 - await router.replace({ - path: LOGIN_PATH, - query: redirect - ? { - redirect: encodeURIComponent(router.currentRoute.value.fullPath), - } - : {}, - }); - } - - async function fetchUserInfo() { - let userInfo: null | UserInfo = null; - userInfo = await getUserInfoApi(); - userStore.setUserInfo(userInfo); - return userInfo; - } - - function $reset() { - loginLoading.value = false; - } - - return { - $reset, - authLogin, - fetchUserInfo, - loginLoading, - logout, - }; -}); diff --git a/apps/web-antd/src/store/index.ts b/apps/web-antd/src/store/index.ts deleted file mode 100644 index 269586ee..00000000 --- a/apps/web-antd/src/store/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth'; diff --git a/apps/web-antd/src/views/_core/README.md b/apps/web-antd/src/views/_core/README.md deleted file mode 100644 index 8248afe6..00000000 --- a/apps/web-antd/src/views/_core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# \_core - -此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。 diff --git a/apps/web-antd/src/views/_core/about/index.vue b/apps/web-antd/src/views/_core/about/index.vue deleted file mode 100644 index 0ee52433..00000000 --- a/apps/web-antd/src/views/_core/about/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/authentication/code-login.vue b/apps/web-antd/src/views/_core/authentication/code-login.vue deleted file mode 100644 index acfd1fd7..00000000 --- a/apps/web-antd/src/views/_core/authentication/code-login.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/authentication/forget-password.vue b/apps/web-antd/src/views/_core/authentication/forget-password.vue deleted file mode 100644 index fef0d427..00000000 --- a/apps/web-antd/src/views/_core/authentication/forget-password.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/authentication/login.vue b/apps/web-antd/src/views/_core/authentication/login.vue deleted file mode 100644 index 099e4c8c..00000000 --- a/apps/web-antd/src/views/_core/authentication/login.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/authentication/qrcode-login.vue b/apps/web-antd/src/views/_core/authentication/qrcode-login.vue deleted file mode 100644 index 23f5f2da..00000000 --- a/apps/web-antd/src/views/_core/authentication/qrcode-login.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/authentication/register.vue b/apps/web-antd/src/views/_core/authentication/register.vue deleted file mode 100644 index b1a5de72..00000000 --- a/apps/web-antd/src/views/_core/authentication/register.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/fallback/coming-soon.vue b/apps/web-antd/src/views/_core/fallback/coming-soon.vue deleted file mode 100644 index f394930f..00000000 --- a/apps/web-antd/src/views/_core/fallback/coming-soon.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/fallback/forbidden.vue b/apps/web-antd/src/views/_core/fallback/forbidden.vue deleted file mode 100644 index 8ea65fed..00000000 --- a/apps/web-antd/src/views/_core/fallback/forbidden.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/fallback/internal-error.vue b/apps/web-antd/src/views/_core/fallback/internal-error.vue deleted file mode 100644 index 819a47d5..00000000 --- a/apps/web-antd/src/views/_core/fallback/internal-error.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/fallback/not-found.vue b/apps/web-antd/src/views/_core/fallback/not-found.vue deleted file mode 100644 index 4d178e9c..00000000 --- a/apps/web-antd/src/views/_core/fallback/not-found.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/fallback/offline.vue b/apps/web-antd/src/views/_core/fallback/offline.vue deleted file mode 100644 index 5de4a88d..00000000 --- a/apps/web-antd/src/views/_core/fallback/offline.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/_core/profile/base-setting.vue b/apps/web-antd/src/views/_core/profile/base-setting.vue deleted file mode 100644 index aa8a4c26..00000000 --- a/apps/web-antd/src/views/_core/profile/base-setting.vue +++ /dev/null @@ -1,65 +0,0 @@ - - diff --git a/apps/web-antd/src/views/_core/profile/index.vue b/apps/web-antd/src/views/_core/profile/index.vue deleted file mode 100644 index 8740894e..00000000 --- a/apps/web-antd/src/views/_core/profile/index.vue +++ /dev/null @@ -1,49 +0,0 @@ - - diff --git a/apps/web-antd/src/views/_core/profile/notification-setting.vue b/apps/web-antd/src/views/_core/profile/notification-setting.vue deleted file mode 100644 index 324a4b39..00000000 --- a/apps/web-antd/src/views/_core/profile/notification-setting.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/apps/web-antd/src/views/_core/profile/password-setting.vue b/apps/web-antd/src/views/_core/profile/password-setting.vue deleted file mode 100644 index b246bc37..00000000 --- a/apps/web-antd/src/views/_core/profile/password-setting.vue +++ /dev/null @@ -1,66 +0,0 @@ - - diff --git a/apps/web-antd/src/views/_core/profile/security-setting.vue b/apps/web-antd/src/views/_core/profile/security-setting.vue deleted file mode 100644 index be30db58..00000000 --- a/apps/web-antd/src/views/_core/profile/security-setting.vue +++ /dev/null @@ -1,43 +0,0 @@ - - diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue deleted file mode 100644 index f1f0b232..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue deleted file mode 100644 index 190fb41f..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-data.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue deleted file mode 100644 index 02f50912..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-sales.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue deleted file mode 100644 index 0915c7af..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-visits-source.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue deleted file mode 100644 index 7e0f1013..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/analytics/index.vue b/apps/web-antd/src/views/dashboard/analytics/index.vue deleted file mode 100644 index 5e3d6d28..00000000 --- a/apps/web-antd/src/views/dashboard/analytics/index.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/dashboard/workspace/index.vue b/apps/web-antd/src/views/dashboard/workspace/index.vue deleted file mode 100644 index b95d6138..00000000 --- a/apps/web-antd/src/views/dashboard/workspace/index.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - diff --git a/apps/web-antd/src/views/demos/antd/index.vue b/apps/web-antd/src/views/demos/antd/index.vue deleted file mode 100644 index b3b05cc1..00000000 --- a/apps/web-antd/src/views/demos/antd/index.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/apps/web-antd/tailwind.config.mjs b/apps/web-antd/tailwind.config.mjs deleted file mode 100644 index f17f556f..00000000 --- a/apps/web-antd/tailwind.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config'; diff --git a/apps/web-antd/tsconfig.json b/apps/web-antd/tsconfig.json deleted file mode 100644 index 02c287fe..00000000 --- a/apps/web-antd/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/web-app.json", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "#/*": ["./src/*"] - } - }, - "references": [{ "path": "./tsconfig.node.json" }], - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] -} diff --git a/apps/web-antd/tsconfig.node.json b/apps/web-antd/tsconfig.node.json deleted file mode 100644 index c2f0d86c..00000000 --- a/apps/web-antd/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/node.json", - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "noEmit": false - }, - "include": ["vite.config.mts"] -} diff --git a/apps/web-antd/vite.config.mts b/apps/web-antd/vite.config.mts deleted file mode 100644 index b6360f1d..00000000 --- a/apps/web-antd/vite.config.mts +++ /dev/null @@ -1,20 +0,0 @@ -import { defineConfig } from '@vben/vite-config'; - -export default defineConfig(async () => { - return { - application: {}, - vite: { - server: { - proxy: { - '/api': { - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), - // mock代理目标地址 - target: 'http://localhost:5320/api', - ws: true, - }, - }, - }, - }, - }; -}); diff --git a/apps/web-ele/.env b/apps/web-ele/.env deleted file mode 100644 index bb57c865..00000000 --- a/apps/web-ele/.env +++ /dev/null @@ -1,8 +0,0 @@ -# 应用标题 -VITE_APP_TITLE=Vben Admin Ele - -# 应用命名空间,用于缓存、store等功能的前缀,确保隔离 -VITE_APP_NAMESPACE=vben-web-ele - -# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 -VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key diff --git a/apps/web-ele/.env.analyze b/apps/web-ele/.env.analyze deleted file mode 100644 index ffafa8dd..00000000 --- a/apps/web-ele/.env.analyze +++ /dev/null @@ -1,7 +0,0 @@ -# public path -VITE_BASE=/ - -# Basic interface address SPA -VITE_GLOB_API_URL=/api - -VITE_VISUALIZER=true diff --git a/apps/web-ele/.env.development b/apps/web-ele/.env.development deleted file mode 100644 index 8bcb432e..00000000 --- a/apps/web-ele/.env.development +++ /dev/null @@ -1,16 +0,0 @@ -# 端口号 -VITE_PORT=5777 - -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=/api - -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=true - -# 是否打开 devtools,true 为打开,false 为关闭 -VITE_DEVTOOLS=false - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true diff --git a/apps/web-ele/.env.production b/apps/web-ele/.env.production deleted file mode 100644 index 5375847a..00000000 --- a/apps/web-ele/.env.production +++ /dev/null @@ -1,19 +0,0 @@ -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=https://mock-napi.vben.pro/api - -# 是否开启压缩,可以设置为 none, brotli, gzip -VITE_COMPRESS=none - -# 是否开启 PWA -VITE_PWA=false - -# vue-router 的模式 -VITE_ROUTER_HISTORY=hash - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true - -# 打包后是否生成dist.zip -VITE_ARCHIVER=true diff --git a/apps/web-ele/index.html b/apps/web-ele/index.html deleted file mode 100644 index 2b59b8d7..00000000 --- a/apps/web-ele/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - <%= VITE_APP_TITLE %> - - - - -
- - - diff --git a/apps/web-ele/package.json b/apps/web-ele/package.json deleted file mode 100644 index abbedb63..00000000 --- a/apps/web-ele/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@vben/web-ele", - "version": "5.5.9", - "homepage": "https://vben.pro", - "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", - "repository": { - "type": "git", - "url": "git+https://github.com/vbenjs/vue-vben-admin.git", - "directory": "apps/web-ele" - }, - "license": "MIT", - "author": { - "name": "vben", - "email": "ann.vben@gmail.com", - "url": "https://github.com/anncwb" - }, - "type": "module", - "scripts": { - "build": "pnpm vite build --mode production", - "build:analyze": "pnpm vite build --mode analyze", - "dev": "pnpm vite --mode development", - "preview": "vite preview", - "typecheck": "vue-tsc --noEmit --skipLibCheck" - }, - "imports": { - "#/*": "./src/*" - }, - "dependencies": { - "@vben/access": "workspace:*", - "@vben/common-ui": "workspace:*", - "@vben/constants": "workspace:*", - "@vben/hooks": "workspace:*", - "@vben/icons": "workspace:*", - "@vben/layouts": "workspace:*", - "@vben/locales": "workspace:*", - "@vben/plugins": "workspace:*", - "@vben/preferences": "workspace:*", - "@vben/request": "workspace:*", - "@vben/stores": "workspace:*", - "@vben/styles": "workspace:*", - "@vben/types": "workspace:*", - "@vben/utils": "workspace:*", - "@vueuse/core": "catalog:", - "dayjs": "catalog:", - "element-plus": "catalog:", - "pinia": "catalog:", - "vue": "catalog:", - "vue-router": "catalog:" - }, - "devDependencies": { - "unplugin-element-plus": "catalog:" - } -} diff --git a/apps/web-ele/postcss.config.mjs b/apps/web-ele/postcss.config.mjs deleted file mode 100644 index 3d807045..00000000 --- a/apps/web-ele/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-ele/public/favicon.ico b/apps/web-ele/public/favicon.ico deleted file mode 100644 index fcf9818e..00000000 Binary files a/apps/web-ele/public/favicon.ico and /dev/null differ diff --git a/apps/web-ele/src/adapter/component/index.ts b/apps/web-ele/src/adapter/component/index.ts deleted file mode 100644 index 79a46360..00000000 --- a/apps/web-ele/src/adapter/component/index.ts +++ /dev/null @@ -1,331 +0,0 @@ -/** - * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用 - * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, - */ - -import type { Component } from 'vue'; - -import type { BaseFormComponentType } from '@vben/common-ui'; -import type { Recordable } from '@vben/types'; - -import { defineAsyncComponent, defineComponent, h, ref } from 'vue'; - -import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -import { ElNotification } from 'element-plus'; - -const ElButton = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/button/index'), - import('element-plus/es/components/button/style/css'), - ]).then(([res]) => res.ElButton), -); -const ElCheckbox = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/checkbox/index'), - import('element-plus/es/components/checkbox/style/css'), - ]).then(([res]) => res.ElCheckbox), -); -const ElCheckboxButton = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/checkbox/index'), - import('element-plus/es/components/checkbox-button/style/css'), - ]).then(([res]) => res.ElCheckboxButton), -); -const ElCheckboxGroup = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/checkbox/index'), - import('element-plus/es/components/checkbox-group/style/css'), - ]).then(([res]) => res.ElCheckboxGroup), -); -const ElDatePicker = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/date-picker/index'), - import('element-plus/es/components/date-picker/style/css'), - ]).then(([res]) => res.ElDatePicker), -); -const ElDivider = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/divider/index'), - import('element-plus/es/components/divider/style/css'), - ]).then(([res]) => res.ElDivider), -); -const ElInput = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/input/index'), - import('element-plus/es/components/input/style/css'), - ]).then(([res]) => res.ElInput), -); -const ElInputNumber = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/input-number/index'), - import('element-plus/es/components/input-number/style/css'), - ]).then(([res]) => res.ElInputNumber), -); -const ElRadio = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/radio/index'), - import('element-plus/es/components/radio/style/css'), - ]).then(([res]) => res.ElRadio), -); -const ElRadioButton = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/radio/index'), - import('element-plus/es/components/radio-button/style/css'), - ]).then(([res]) => res.ElRadioButton), -); -const ElRadioGroup = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/radio/index'), - import('element-plus/es/components/radio-group/style/css'), - ]).then(([res]) => res.ElRadioGroup), -); -const ElSelectV2 = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/select-v2/index'), - import('element-plus/es/components/select-v2/style/css'), - ]).then(([res]) => res.ElSelectV2), -); -const ElSpace = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/space/index'), - import('element-plus/es/components/space/style/css'), - ]).then(([res]) => res.ElSpace), -); -const ElSwitch = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/switch/index'), - import('element-plus/es/components/switch/style/css'), - ]).then(([res]) => res.ElSwitch), -); -const ElTimePicker = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/time-picker/index'), - import('element-plus/es/components/time-picker/style/css'), - ]).then(([res]) => res.ElTimePicker), -); -const ElTreeSelect = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/tree-select/index'), - import('element-plus/es/components/tree-select/style/css'), - ]).then(([res]) => res.ElTreeSelect), -); -const ElUpload = defineAsyncComponent(() => - Promise.all([ - import('element-plus/es/components/upload/index'), - import('element-plus/es/components/upload/style/css'), - ]).then(([res]) => res.ElUpload), -); - -const withDefaultPlaceholder = ( - component: T, - type: 'input' | 'select', - componentProps: Recordable = {}, -) => { - return defineComponent({ - name: component.name, - inheritAttrs: false, - setup: (props: any, { attrs, expose, slots }) => { - const placeholder = - props?.placeholder || - attrs?.placeholder || - $t(`ui.placeholder.${type}`); - // 透传组件暴露的方法 - const innerRef = ref(); - expose( - new Proxy( - {}, - { - get: (_target, key) => innerRef.value?.[key], - has: (_target, key) => key in (innerRef.value || {}), - }, - ), - ); - return () => - h( - component, - { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, - slots, - ); - }, - }); -}; - -// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 -export type ComponentType = - | 'ApiSelect' - | 'ApiTreeSelect' - | 'Checkbox' - | 'CheckboxGroup' - | 'DatePicker' - | 'Divider' - | 'IconPicker' - | 'Input' - | 'InputNumber' - | 'RadioGroup' - | 'Select' - | 'Space' - | 'Switch' - | 'TimePicker' - | 'TreeSelect' - | 'Upload' - | BaseFormComponentType; - -async function initComponentAdapter() { - const components: Partial> = { - // 如果你的组件体积比较大,可以使用异步加载 - // Button: () => - // import('xxx').then((res) => res.Button), - ApiSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiSelect', - }, - 'select', - { - component: ElSelectV2, - loadingSlot: 'loading', - visibleEvent: 'onVisibleChange', - }, - ), - ApiTreeSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiTreeSelect', - }, - 'select', - { - component: ElTreeSelect, - props: { label: 'label', children: 'children' }, - nodeKey: 'value', - loadingSlot: 'loading', - optionsPropName: 'data', - visibleEvent: 'onVisibleChange', - }, - ), - Checkbox: ElCheckbox, - CheckboxGroup: (props, { attrs, slots }) => { - let defaultSlot; - if (Reflect.has(slots, 'default')) { - defaultSlot = slots.default; - } else { - const { options, isButton } = attrs; - if (Array.isArray(options)) { - defaultSlot = () => - options.map((option) => - h(isButton ? ElCheckboxButton : ElCheckbox, option), - ); - } - } - return h( - ElCheckboxGroup, - { ...props, ...attrs }, - { ...slots, default: defaultSlot }, - ); - }, - // 自定义默认按钮 - DefaultButton: (props, { attrs, slots }) => { - return h(ElButton, { ...props, attrs, type: 'info' }, slots); - }, - // 自定义主要按钮 - PrimaryButton: (props, { attrs, slots }) => { - return h(ElButton, { ...props, attrs, type: 'primary' }, slots); - }, - Divider: ElDivider, - IconPicker: withDefaultPlaceholder(IconPicker, 'select', { - iconSlot: 'append', - modelValueProp: 'model-value', - inputComponent: ElInput, - }), - Input: withDefaultPlaceholder(ElInput, 'input'), - InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'), - RadioGroup: (props, { attrs, slots }) => { - let defaultSlot; - if (Reflect.has(slots, 'default')) { - defaultSlot = slots.default; - } else { - const { options } = attrs; - if (Array.isArray(options)) { - defaultSlot = () => - options.map((option) => - h(attrs.isButton ? ElRadioButton : ElRadio, option), - ); - } - } - return h( - ElRadioGroup, - { ...props, ...attrs }, - { ...slots, default: defaultSlot }, - ); - }, - Select: (props, { attrs, slots }) => { - return h(ElSelectV2, { ...props, attrs }, slots); - }, - Space: ElSpace, - Switch: ElSwitch, - TimePicker: (props, { attrs, slots }) => { - const { name, id, isRange } = props; - const extraProps: Recordable = {}; - if (isRange) { - if (name && !Array.isArray(name)) { - extraProps.name = [name, `${name}_end`]; - } - if (id && !Array.isArray(id)) { - extraProps.id = [id, `${id}_end`]; - } - } - return h( - ElTimePicker, - { - ...props, - ...attrs, - ...extraProps, - }, - slots, - ); - }, - DatePicker: (props, { attrs, slots }) => { - const { name, id, type } = props; - const extraProps: Recordable = {}; - if (type && type.includes('range')) { - if (name && !Array.isArray(name)) { - extraProps.name = [name, `${name}_end`]; - } - if (id && !Array.isArray(id)) { - extraProps.id = [id, `${id}_end`]; - } - } - return h( - ElDatePicker, - { - ...props, - ...attrs, - ...extraProps, - }, - slots, - ); - }, - TreeSelect: withDefaultPlaceholder(ElTreeSelect, 'select'), - Upload: ElUpload, - }; - - // 将组件注册到全局共享状态中 - globalShareState.setComponents(components); - - // 定义全局共享状态中的消息提示 - globalShareState.defineMessage({ - // 复制成功消息提示 - copyPreferencesSuccess: (title, content) => { - ElNotification({ - title, - message: content, - position: 'bottom-right', - duration: 0, - type: 'success', - }); - }, - }); -} - -export { initComponentAdapter }; diff --git a/apps/web-ele/src/adapter/form.ts b/apps/web-ele/src/adapter/form.ts deleted file mode 100644 index 936c3fe4..00000000 --- a/apps/web-ele/src/adapter/form.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { - VbenFormSchema as FormSchema, - VbenFormProps, -} from '@vben/common-ui'; - -import type { ComponentType } from './component'; - -import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -async function initSetupVbenForm() { - setupVbenForm({ - config: { - modelPropNameMap: { - Upload: 'fileList', - CheckboxGroup: 'model-value', - }, - }, - defineRules: { - required: (value, _params, ctx) => { - if (value === undefined || value === null || value.length === 0) { - return $t('ui.formRules.required', [ctx.label]); - } - return true; - }, - selectRequired: (value, _params, ctx) => { - if (value === undefined || value === null) { - return $t('ui.formRules.selectRequired', [ctx.label]); - } - return true; - }, - }, - }); -} - -const useVbenForm = useForm; - -export { initSetupVbenForm, useVbenForm, z }; - -export type VbenFormSchema = FormSchema; -export type { VbenFormProps }; diff --git a/apps/web-ele/src/adapter/vxe-table.ts b/apps/web-ele/src/adapter/vxe-table.ts deleted file mode 100644 index 40b8179d..00000000 --- a/apps/web-ele/src/adapter/vxe-table.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { VxeTableGridOptions } from '@vben/plugins/vxe-table'; - -import { h } from 'vue'; - -import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; - -import { ElButton, ElImage } from 'element-plus'; - -import { useVbenForm } from './form'; - -setupVbenVxeTable({ - configVxeTable: (vxeUI) => { - vxeUI.setConfig({ - grid: { - align: 'center', - border: false, - columnConfig: { - resizable: true, - }, - minHeight: 180, - formConfig: { - // 全局禁用vxe-table的表单配置,使用formOptions - enabled: false, - }, - proxyConfig: { - autoLoad: true, - response: { - result: 'items', - total: 'total', - list: 'items', - }, - showActiveMsg: true, - showResponseMsg: false, - }, - round: true, - showOverflow: true, - size: 'small', - } as VxeTableGridOptions, - }); - - // 表格配置项可以用 cellRender: { name: 'CellImage' }, - vxeUI.renderer.add('CellImage', { - renderTableDefault(_renderOpts, params) { - const { column, row } = params; - const src = row[column.field]; - return h(ElImage, { src, previewSrcList: [src] }); - }, - }); - - // 表格配置项可以用 cellRender: { name: 'CellLink' }, - vxeUI.renderer.add('CellLink', { - renderTableDefault(renderOpts) { - const { props } = renderOpts; - return h( - ElButton, - { size: 'small', link: true }, - { default: () => props?.text }, - ); - }, - }); - - // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 - // vxeUI.formats.add - }, - useVbenForm, -}); - -export { useVbenVxeGrid }; - -export type * from '@vben/plugins/vxe-table'; diff --git a/apps/web-ele/src/api/core/auth.ts b/apps/web-ele/src/api/core/auth.ts deleted file mode 100644 index 71d9f994..00000000 --- a/apps/web-ele/src/api/core/auth.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { baseRequestClient, requestClient } from '#/api/request'; - -export namespace AuthApi { - /** 登录接口参数 */ - export interface LoginParams { - password?: string; - username?: string; - } - - /** 登录接口返回值 */ - export interface LoginResult { - accessToken: string; - } - - export interface RefreshTokenResult { - data: string; - status: number; - } -} - -/** - * 登录 - */ -export async function loginApi(data: AuthApi.LoginParams) { - return requestClient.post('/auth/login', data); -} - -/** - * 刷新accessToken - */ -export async function refreshTokenApi() { - return baseRequestClient.post('/auth/refresh', { - withCredentials: true, - }); -} - -/** - * 退出登录 - */ -export async function logoutApi() { - return baseRequestClient.post('/auth/logout', { - withCredentials: true, - }); -} - -/** - * 获取用户权限码 - */ -export async function getAccessCodesApi() { - return requestClient.get('/auth/codes'); -} diff --git a/apps/web-ele/src/api/core/index.ts b/apps/web-ele/src/api/core/index.ts deleted file mode 100644 index 28a5aef4..00000000 --- a/apps/web-ele/src/api/core/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './auth'; -export * from './menu'; -export * from './user'; diff --git a/apps/web-ele/src/api/core/menu.ts b/apps/web-ele/src/api/core/menu.ts deleted file mode 100644 index 9ef60b11..00000000 --- a/apps/web-ele/src/api/core/menu.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { RouteRecordStringComponent } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户所有菜单 - */ -export async function getAllMenusApi() { - return requestClient.get('/menu/all'); -} diff --git a/apps/web-ele/src/api/core/user.ts b/apps/web-ele/src/api/core/user.ts deleted file mode 100644 index 7e28ea84..00000000 --- a/apps/web-ele/src/api/core/user.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UserInfo } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户信息 - */ -export async function getUserInfoApi() { - return requestClient.get('/user/info'); -} diff --git a/apps/web-ele/src/api/index.ts b/apps/web-ele/src/api/index.ts deleted file mode 100644 index 4b0e0413..00000000 --- a/apps/web-ele/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './core'; diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts deleted file mode 100644 index 203b35bf..00000000 --- a/apps/web-ele/src/api/request.ts +++ /dev/null @@ -1,113 +0,0 @@ -/** - * 该文件可自行根据业务逻辑进行调整 - */ -import type { RequestClientOptions } from '@vben/request'; - -import { useAppConfig } from '@vben/hooks'; -import { preferences } from '@vben/preferences'; -import { - authenticateResponseInterceptor, - defaultResponseInterceptor, - errorMessageResponseInterceptor, - RequestClient, -} from '@vben/request'; -import { useAccessStore } from '@vben/stores'; - -import { ElMessage } from 'element-plus'; - -import { useAuthStore } from '#/store'; - -import { refreshTokenApi } from './core'; - -const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); - -function createRequestClient(baseURL: string, options?: RequestClientOptions) { - const client = new RequestClient({ - ...options, - baseURL, - }); - - /** - * 重新认证逻辑 - */ - async function doReAuthenticate() { - console.warn('Access token or refresh token is invalid or expired. '); - const accessStore = useAccessStore(); - const authStore = useAuthStore(); - accessStore.setAccessToken(null); - if ( - preferences.app.loginExpiredMode === 'modal' && - accessStore.isAccessChecked - ) { - accessStore.setLoginExpired(true); - } else { - await authStore.logout(); - } - } - - /** - * 刷新token逻辑 - */ - async function doRefreshToken() { - const accessStore = useAccessStore(); - const resp = await refreshTokenApi(); - const newToken = resp.data; - accessStore.setAccessToken(newToken); - return newToken; - } - - function formatToken(token: null | string) { - return token ? `Bearer ${token}` : null; - } - - // 请求头处理 - client.addRequestInterceptor({ - fulfilled: async (config) => { - const accessStore = useAccessStore(); - - config.headers.Authorization = formatToken(accessStore.accessToken); - config.headers['Accept-Language'] = preferences.app.locale; - return config; - }, - }); - - // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); - - // token过期的处理 - client.addResponseInterceptor( - authenticateResponseInterceptor({ - client, - doReAuthenticate, - doRefreshToken, - enableRefreshToken: preferences.app.enableRefreshToken, - formatToken, - }), - ); - - // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里 - client.addResponseInterceptor( - errorMessageResponseInterceptor((msg: string, error) => { - // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg - // 当前mock接口返回的错误字段是 error 或者 message - const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; - // 如果没有错误信息,则会根据状态码进行提示 - ElMessage.error(errorMessage || msg); - }), - ); - - return client; -} - -export const requestClient = createRequestClient(apiURL, { - responseReturn: 'data', -}); - -export const baseRequestClient = new RequestClient({ baseURL: apiURL }); diff --git a/apps/web-ele/src/app.vue b/apps/web-ele/src/app.vue deleted file mode 100644 index 1217658d..00000000 --- a/apps/web-ele/src/app.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/apps/web-ele/src/bootstrap.ts b/apps/web-ele/src/bootstrap.ts deleted file mode 100644 index e5befb5a..00000000 --- a/apps/web-ele/src/bootstrap.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { createApp, watchEffect } from 'vue'; - -import { registerAccessDirective } from '@vben/access'; -import { registerLoadingDirective } from '@vben/common-ui'; -import { preferences } from '@vben/preferences'; -import { initStores } from '@vben/stores'; -import '@vben/styles'; -import '@vben/styles/ele'; - -import { useTitle } from '@vueuse/core'; -import { ElLoading } from 'element-plus'; - -import { $t, setupI18n } from '#/locales'; - -import { initComponentAdapter } from './adapter/component'; -import { initSetupVbenForm } from './adapter/form'; -import App from './app.vue'; -import { router } from './router'; - -async function bootstrap(namespace: string) { - // 初始化组件适配器 - await initComponentAdapter(); - - // 初始化表单组件 - await initSetupVbenForm(); - - // // 设置弹窗的默认配置 - // setDefaultModalProps({ - // fullscreenButton: false, - // }); - // // 设置抽屉的默认配置 - // setDefaultDrawerProps({ - // zIndex: 2000, - // }); - const app = createApp(App); - - // 注册Element Plus提供的v-loading指令 - app.directive('loading', ElLoading.directive); - - // 注册Vben提供的v-loading和v-spinning指令 - registerLoadingDirective(app, { - loading: false, // Vben提供的v-loading指令和Element Plus提供的v-loading指令二选一即可,此处false表示不注册Vben提供的v-loading指令 - spinning: 'spinning', - }); - - // 国际化 i18n 配置 - await setupI18n(app); - - // 配置 pinia-tore - await initStores(app, { namespace }); - - // 安装权限指令 - registerAccessDirective(app); - - // 初始化 tippy - const { initTippy } = await import('@vben/common-ui/es/tippy'); - initTippy(app); - - // 配置路由及路由守卫 - app.use(router); - - // 配置Motion插件 - const { MotionPlugin } = await import('@vben/plugins/motion'); - app.use(MotionPlugin); - - // 动态更新标题 - watchEffect(() => { - if (preferences.app.dynamicTitle) { - const routeTitle = router.currentRoute.value.meta?.title; - const pageTitle = - (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; - useTitle(pageTitle); - } - }); - - app.mount('#app'); -} - -export { bootstrap }; diff --git a/apps/web-ele/src/layouts/auth.vue b/apps/web-ele/src/layouts/auth.vue deleted file mode 100644 index 8ba66e85..00000000 --- a/apps/web-ele/src/layouts/auth.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/apps/web-ele/src/layouts/basic.vue b/apps/web-ele/src/layouts/basic.vue deleted file mode 100644 index 2226c68a..00000000 --- a/apps/web-ele/src/layouts/basic.vue +++ /dev/null @@ -1,206 +0,0 @@ - - - diff --git a/apps/web-ele/src/layouts/index.ts b/apps/web-ele/src/layouts/index.ts deleted file mode 100644 index a4320780..00000000 --- a/apps/web-ele/src/layouts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -const BasicLayout = () => import('./basic.vue'); -const AuthPageLayout = () => import('./auth.vue'); - -const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView); - -export { AuthPageLayout, BasicLayout, IFrameView }; diff --git a/apps/web-ele/src/locales/README.md b/apps/web-ele/src/locales/README.md deleted file mode 100644 index 7b451032..00000000 --- a/apps/web-ele/src/locales/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# locale - -每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。 diff --git a/apps/web-ele/src/locales/index.ts b/apps/web-ele/src/locales/index.ts deleted file mode 100644 index 57b87dfd..00000000 --- a/apps/web-ele/src/locales/index.ts +++ /dev/null @@ -1,102 +0,0 @@ -import type { Language } from 'element-plus/es/locale'; - -import type { App } from 'vue'; - -import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales'; - -import { ref } from 'vue'; - -import { - $t, - setupI18n as coreSetup, - loadLocalesMapFromDir, -} from '@vben/locales'; -import { preferences } from '@vben/preferences'; - -import dayjs from 'dayjs'; -import enLocale from 'element-plus/es/locale/lang/en'; -import defaultLocale from 'element-plus/es/locale/lang/zh-cn'; - -const elementLocale = ref(defaultLocale); - -const modules = import.meta.glob('./langs/**/*.json'); - -const localesMap = loadLocalesMapFromDir( - /\.\/langs\/([^/]+)\/(.*)\.json$/, - modules, -); -/** - * 加载应用特有的语言包 - * 这里也可以改造为从服务端获取翻译数据 - * @param lang - */ -async function loadMessages(lang: SupportedLanguagesType) { - const [appLocaleMessages] = await Promise.all([ - localesMap[lang]?.(), - loadThirdPartyMessage(lang), - ]); - return appLocaleMessages?.default; -} - -/** - * 加载第三方组件库的语言包 - * @param lang - */ -async function loadThirdPartyMessage(lang: SupportedLanguagesType) { - await Promise.all([loadElementLocale(lang), loadDayjsLocale(lang)]); -} - -/** - * 加载dayjs的语言包 - * @param lang - */ -async function loadDayjsLocale(lang: SupportedLanguagesType) { - let locale; - switch (lang) { - case 'en-US': { - locale = await import('dayjs/locale/en'); - break; - } - case 'zh-CN': { - locale = await import('dayjs/locale/zh-cn'); - break; - } - // 默认使用英语 - default: { - locale = await import('dayjs/locale/en'); - } - } - if (locale) { - dayjs.locale(locale); - } else { - console.error(`Failed to load dayjs locale for ${lang}`); - } -} - -/** - * 加载element-plus的语言包 - * @param lang - */ -async function loadElementLocale(lang: SupportedLanguagesType) { - switch (lang) { - case 'en-US': { - elementLocale.value = enLocale; - break; - } - case 'zh-CN': { - elementLocale.value = defaultLocale; - break; - } - } -} - -async function setupI18n(app: App, options: LocaleSetupOptions = {}) { - await coreSetup(app, { - defaultLocale: preferences.app.locale, - loadMessages, - missingWarn: !import.meta.env.PROD, - ...options, - }); -} - -export { $t, elementLocale, setupI18n }; diff --git a/apps/web-ele/src/locales/langs/en-US/demos.json b/apps/web-ele/src/locales/langs/en-US/demos.json deleted file mode 100644 index cc404511..00000000 --- a/apps/web-ele/src/locales/langs/en-US/demos.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "title": "Demos", - "elementPlus": "Element Plus", - "form": "Form", - "vben": { - "title": "Project", - "about": "About", - "document": "Document", - "antdv": "Ant Design Vue Version", - "naive-ui": "Naive UI Version", - "element-plus": "Element Plus Version", - "tdesign": "TDesign Vue Version" - } -} diff --git a/apps/web-ele/src/locales/langs/en-US/page.json b/apps/web-ele/src/locales/langs/en-US/page.json deleted file mode 100644 index 39f1641c..00000000 --- a/apps/web-ele/src/locales/langs/en-US/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "Login", - "register": "Register", - "codeLogin": "Code Login", - "qrcodeLogin": "Qr Code Login", - "forgetPassword": "Forget Password", - "profile": "Profile" - }, - "dashboard": { - "title": "Dashboard", - "analytics": "Analytics", - "workspace": "Workspace" - } -} diff --git a/apps/web-ele/src/locales/langs/zh-CN/demos.json b/apps/web-ele/src/locales/langs/zh-CN/demos.json deleted file mode 100644 index f8379c36..00000000 --- a/apps/web-ele/src/locales/langs/zh-CN/demos.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "title": "演示", - "elementPlus": "Element Plus", - "form": "表单演示", - "vben": { - "title": "项目", - "about": "关于", - "document": "文档", - "antdv": "Ant Design Vue 版本", - "naive-ui": "Naive UI 版本", - "element-plus": "Element Plus 版本", - "tdesign": "TDesign Vue 版本" - } -} diff --git a/apps/web-ele/src/locales/langs/zh-CN/page.json b/apps/web-ele/src/locales/langs/zh-CN/page.json deleted file mode 100644 index 2192d1d5..00000000 --- a/apps/web-ele/src/locales/langs/zh-CN/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "登录", - "register": "注册", - "codeLogin": "验证码登录", - "qrcodeLogin": "二维码登录", - "forgetPassword": "忘记密码", - "profile": "个人中心" - }, - "dashboard": { - "title": "概览", - "analytics": "分析页", - "workspace": "工作台" - } -} diff --git a/apps/web-ele/src/main.ts b/apps/web-ele/src/main.ts deleted file mode 100644 index 5d728a02..00000000 --- a/apps/web-ele/src/main.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { initPreferences } from '@vben/preferences'; -import { unmountGlobalLoading } from '@vben/utils'; - -import { overridesPreferences } from './preferences'; - -/** - * 应用初始化完成之后再进行页面加载渲染 - */ -async function initApplication() { - // name用于指定项目唯一标识 - // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据 - const env = import.meta.env.PROD ? 'prod' : 'dev'; - const appVersion = import.meta.env.VITE_APP_VERSION; - const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`; - - // app偏好设置初始化 - await initPreferences({ - namespace, - overrides: overridesPreferences, - }); - - // 启动应用并挂载 - // vue应用主要逻辑及视图 - const { bootstrap } = await import('./bootstrap'); - await bootstrap(namespace); - - // 移除并销毁loading - unmountGlobalLoading(); -} - -initApplication(); diff --git a/apps/web-ele/src/preferences.ts b/apps/web-ele/src/preferences.ts deleted file mode 100644 index b2e9ace4..00000000 --- a/apps/web-ele/src/preferences.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineOverridesPreferences } from '@vben/preferences'; - -/** - * @description 项目配置文件 - * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 - * !!! 更改配置后请清空缓存,否则可能不生效 - */ -export const overridesPreferences = defineOverridesPreferences({ - // overrides - app: { - name: import.meta.env.VITE_APP_TITLE, - }, -}); diff --git a/apps/web-ele/src/router/access.ts b/apps/web-ele/src/router/access.ts deleted file mode 100644 index 2d07c892..00000000 --- a/apps/web-ele/src/router/access.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { - ComponentRecordType, - GenerateMenuAndRoutesOptions, -} from '@vben/types'; - -import { generateAccessible } from '@vben/access'; -import { preferences } from '@vben/preferences'; - -import { ElMessage } from 'element-plus'; - -import { getAllMenusApi } from '#/api'; -import { BasicLayout, IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue'); - -async function generateAccess(options: GenerateMenuAndRoutesOptions) { - const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); - - const layoutMap: ComponentRecordType = { - BasicLayout, - IFrameView, - }; - - return await generateAccessible(preferences.app.accessMode, { - ...options, - fetchMenuListAsync: async () => { - ElMessage({ - duration: 1500, - message: `${$t('common.loadingMenu')}...`, - }); - return await getAllMenusApi(); - }, - // 可以指定没有权限跳转403页面 - forbiddenComponent, - // 如果 route.meta.menuVisibleWithForbidden = true - layoutMap, - pageMap, - }); -} - -export { generateAccess }; diff --git a/apps/web-ele/src/router/guard.ts b/apps/web-ele/src/router/guard.ts deleted file mode 100644 index a1ad6d88..00000000 --- a/apps/web-ele/src/router/guard.ts +++ /dev/null @@ -1,133 +0,0 @@ -import type { Router } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { useAccessStore, useUserStore } from '@vben/stores'; -import { startProgress, stopProgress } from '@vben/utils'; - -import { accessRoutes, coreRouteNames } from '#/router/routes'; -import { useAuthStore } from '#/store'; - -import { generateAccess } from './access'; - -/** - * 通用守卫配置 - * @param router - */ -function setupCommonGuard(router: Router) { - // 记录已经加载的页面 - const loadedPaths = new Set(); - - router.beforeEach((to) => { - to.meta.loaded = loadedPaths.has(to.path); - - // 页面加载进度条 - if (!to.meta.loaded && preferences.transition.progress) { - startProgress(); - } - return true; - }); - - router.afterEach((to) => { - // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行 - - loadedPaths.add(to.path); - - // 关闭页面加载进度条 - if (preferences.transition.progress) { - stopProgress(); - } - }); -} - -/** - * 权限访问守卫配置 - * @param router - */ -function setupAccessGuard(router: Router) { - router.beforeEach(async (to, from) => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const authStore = useAuthStore(); - - // 基本路由,这些路由不需要进入权限拦截 - if (coreRouteNames.includes(to.name as string)) { - if (to.path === LOGIN_PATH && accessStore.accessToken) { - return decodeURIComponent( - (to.query?.redirect as string) || - userStore.userInfo?.homePath || - preferences.app.defaultHomePath, - ); - } - return true; - } - - // accessToken 检查 - if (!accessStore.accessToken) { - // 明确声明忽略权限访问权限,则可以访问 - if (to.meta.ignoreAccess) { - return true; - } - - // 没有访问权限,跳转登录页面 - if (to.fullPath !== LOGIN_PATH) { - return { - path: LOGIN_PATH, - // 如不需要,直接删除 query - query: - to.fullPath === preferences.app.defaultHomePath - ? {} - : { redirect: encodeURIComponent(to.fullPath) }, - // 携带当前跳转的页面,登录后重新跳转该页面 - replace: true, - }; - } - return to; - } - - // 是否已经生成过动态路由 - if (accessStore.isAccessChecked) { - return true; - } - - // 生成路由表 - // 当前登录用户拥有的角色标识列表 - const userInfo = userStore.userInfo || (await authStore.fetchUserInfo()); - const userRoles = userInfo.roles ?? []; - - // 生成菜单和路由 - const { accessibleMenus, accessibleRoutes } = await generateAccess({ - roles: userRoles, - router, - // 则会在菜单中显示,但是访问会被重定向到403 - routes: accessRoutes, - }); - - // 保存菜单信息和路由信息 - accessStore.setAccessMenus(accessibleMenus); - accessStore.setAccessRoutes(accessibleRoutes); - accessStore.setIsAccessChecked(true); - const redirectPath = (from.query.redirect ?? - (to.path === preferences.app.defaultHomePath - ? userInfo.homePath || preferences.app.defaultHomePath - : to.fullPath)) as string; - - return { - ...router.resolve(decodeURIComponent(redirectPath)), - replace: true, - }; - }); -} - -/** - * 项目守卫配置 - * @param router - */ -function createRouterGuard(router: Router) { - /** 通用 */ - setupCommonGuard(router); - /** 权限访问 */ - setupAccessGuard(router); -} - -export { createRouterGuard }; diff --git a/apps/web-ele/src/router/index.ts b/apps/web-ele/src/router/index.ts deleted file mode 100644 index 48402303..00000000 --- a/apps/web-ele/src/router/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - createRouter, - createWebHashHistory, - createWebHistory, -} from 'vue-router'; - -import { resetStaticRoutes } from '@vben/utils'; - -import { createRouterGuard } from './guard'; -import { routes } from './routes'; - -/** - * @zh_CN 创建vue-router实例 - */ -const router = createRouter({ - history: - import.meta.env.VITE_ROUTER_HISTORY === 'hash' - ? createWebHashHistory(import.meta.env.VITE_BASE) - : createWebHistory(import.meta.env.VITE_BASE), - // 应该添加到路由的初始路由列表。 - routes, - scrollBehavior: (to, _from, savedPosition) => { - if (savedPosition) { - return savedPosition; - } - return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; - }, - // 是否应该禁止尾部斜杠。 - // strict: true, -}); - -const resetRoutes = () => resetStaticRoutes(router, routes); - -// 创建路由守卫 -createRouterGuard(router); - -export { resetRoutes, router }; diff --git a/apps/web-ele/src/router/routes/core.ts b/apps/web-ele/src/router/routes/core.ts deleted file mode 100644 index 949b0b65..00000000 --- a/apps/web-ele/src/router/routes/core.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; - -import { $t } from '#/locales'; - -const BasicLayout = () => import('#/layouts/basic.vue'); -const AuthPageLayout = () => import('#/layouts/auth.vue'); -/** 全局404页面 */ -const fallbackNotFoundRoute: RouteRecordRaw = { - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - hideInBreadcrumb: true, - hideInMenu: true, - hideInTab: true, - title: '404', - }, - name: 'FallbackNotFound', - path: '/:path(.*)*', -}; - -/** 基本路由,这些路由是必须存在的 */ -const coreRoutes: RouteRecordRaw[] = [ - /** - * 根路由 - * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 - * 此路由必须存在,且不应修改 - */ - { - component: BasicLayout, - meta: { - hideInBreadcrumb: true, - title: 'Root', - }, - name: 'Root', - path: '/', - redirect: preferences.app.defaultHomePath, - children: [], - }, - { - component: AuthPageLayout, - meta: { - hideInTab: true, - title: 'Authentication', - }, - name: 'Authentication', - path: '/auth', - redirect: LOGIN_PATH, - children: [ - { - name: 'Login', - path: 'login', - component: () => import('#/views/_core/authentication/login.vue'), - meta: { - title: $t('page.auth.login'), - }, - }, - { - name: 'CodeLogin', - path: 'code-login', - component: () => import('#/views/_core/authentication/code-login.vue'), - meta: { - title: $t('page.auth.codeLogin'), - }, - }, - { - name: 'QrCodeLogin', - path: 'qrcode-login', - component: () => - import('#/views/_core/authentication/qrcode-login.vue'), - meta: { - title: $t('page.auth.qrcodeLogin'), - }, - }, - { - name: 'ForgetPassword', - path: 'forget-password', - component: () => - import('#/views/_core/authentication/forget-password.vue'), - meta: { - title: $t('page.auth.forgetPassword'), - }, - }, - { - name: 'Register', - path: 'register', - component: () => import('#/views/_core/authentication/register.vue'), - meta: { - title: $t('page.auth.register'), - }, - }, - ], - }, -]; - -export { coreRoutes, fallbackNotFoundRoute }; diff --git a/apps/web-ele/src/router/routes/index.ts b/apps/web-ele/src/router/routes/index.ts deleted file mode 100644 index e6fb1440..00000000 --- a/apps/web-ele/src/router/routes/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { mergeRouteModules, traverseTreeValues } from '@vben/utils'; - -import { coreRoutes, fallbackNotFoundRoute } from './core'; - -const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { - eager: true, -}); - -// 有需要可以自行打开注释,并创建文件夹 -// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true }); -// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true }); - -/** 动态路由 */ -const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); - -/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ -// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); -// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); -const staticRoutes: RouteRecordRaw[] = []; -const externalRoutes: RouteRecordRaw[] = []; - -/** 路由列表,由基本路由、外部路由和404兜底路由组成 - * 无需走权限验证(会一直显示在菜单中) */ -const routes: RouteRecordRaw[] = [ - ...coreRoutes, - ...externalRoutes, - fallbackNotFoundRoute, -]; - -/** 基本路由列表,这些路由不需要进入权限拦截 */ -const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); - -/** 有权限校验的路由列表,包含动态路由和静态路由 */ -const accessRoutes = [...dynamicRoutes, ...staticRoutes]; -export { accessRoutes, coreRouteNames, routes }; diff --git a/apps/web-ele/src/router/routes/modules/dashboard.ts b/apps/web-ele/src/router/routes/modules/dashboard.ts deleted file mode 100644 index 5254dc65..00000000 --- a/apps/web-ele/src/router/routes/modules/dashboard.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'lucide:layout-dashboard', - order: -1, - title: $t('page.dashboard.title'), - }, - name: 'Dashboard', - path: '/dashboard', - children: [ - { - name: 'Analytics', - path: '/analytics', - component: () => import('#/views/dashboard/analytics/index.vue'), - meta: { - affixTab: true, - icon: 'lucide:area-chart', - title: $t('page.dashboard.analytics'), - }, - }, - { - name: 'Workspace', - path: '/workspace', - component: () => import('#/views/dashboard/workspace/index.vue'), - meta: { - icon: 'carbon:workspace', - title: $t('page.dashboard.workspace'), - }, - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-ele/src/router/routes/modules/demos.ts b/apps/web-ele/src/router/routes/modules/demos.ts deleted file mode 100644 index 907ea3f4..00000000 --- a/apps/web-ele/src/router/routes/modules/demos.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ic:baseline-view-in-ar', - keepAlive: true, - order: 1000, - title: $t('demos.title'), - }, - name: 'Demos', - path: '/demos', - children: [ - { - meta: { - title: $t('demos.elementPlus'), - }, - name: 'NaiveDemos', - path: '/demos/element', - component: () => import('#/views/demos/element/index.vue'), - }, - { - meta: { - title: $t('demos.form'), - }, - name: 'BasicForm', - path: '/demos/form', - component: () => import('#/views/demos/form/basic.vue'), - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-ele/src/router/routes/modules/vben.ts b/apps/web-ele/src/router/routes/modules/vben.ts deleted file mode 100644 index 5c522f30..00000000 --- a/apps/web-ele/src/router/routes/modules/vben.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { - VBEN_ANT_PREVIEW_URL, - VBEN_DOC_URL, - VBEN_GITHUB_URL, - VBEN_LOGO_URL, - VBEN_NAIVE_PREVIEW_URL, - VBEN_TD_PREVIEW_URL, -} from '@vben/constants'; -import { SvgAntdvLogoIcon, SvgTDesignIcon } from '@vben/icons'; - -import { IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - badgeType: 'dot', - icon: VBEN_LOGO_URL, - order: 9998, - title: $t('demos.vben.title'), - }, - name: 'VbenProject', - path: '/vben-admin', - children: [ - { - name: 'VbenDocument', - path: '/vben-admin/document', - component: IFrameView, - meta: { - icon: 'lucide:book-open-text', - link: VBEN_DOC_URL, - title: $t('demos.vben.document'), - }, - }, - { - name: 'VbenGithub', - path: '/vben-admin/github', - component: IFrameView, - meta: { - icon: 'mdi:github', - link: VBEN_GITHUB_URL, - title: 'Github', - }, - }, - { - name: 'VbenNaive', - path: '/vben-admin/naive', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:naiveui', - link: VBEN_NAIVE_PREVIEW_URL, - title: $t('demos.vben.naive-ui'), - }, - }, - { - name: 'VbenAntd', - path: '/vben-admin/antd', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgAntdvLogoIcon, - link: VBEN_ANT_PREVIEW_URL, - title: $t('demos.vben.antdv'), - }, - }, - { - name: 'VbenTDesign', - path: '/vben-admin/tdesign', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgTDesignIcon, - link: VBEN_TD_PREVIEW_URL, - title: $t('demos.vben.tdesign'), - }, - }, - ], - }, - { - name: 'VbenAbout', - path: '/vben-admin/about', - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - title: $t('demos.vben.about'), - order: 9999, - }, - }, - { - name: 'Profile', - path: '/profile', - component: () => import('#/views/_core/profile/index.vue'), - meta: { - icon: 'lucide:user', - hideInMenu: true, - title: $t('page.auth.profile'), - }, - }, -]; - -export default routes; diff --git a/apps/web-ele/src/store/auth.ts b/apps/web-ele/src/store/auth.ts deleted file mode 100644 index 74fadfe2..00000000 --- a/apps/web-ele/src/store/auth.ts +++ /dev/null @@ -1,119 +0,0 @@ -import type { Recordable, UserInfo } from '@vben/types'; - -import { ref } from 'vue'; -import { useRouter } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; - -import { ElNotification } from 'element-plus'; -import { defineStore } from 'pinia'; - -import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api'; -import { $t } from '#/locales'; - -export const useAuthStore = defineStore('auth', () => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const router = useRouter(); - - const loginLoading = ref(false); - - /** - * 异步处理登录操作 - * Asynchronously handle the login process - * @param params 登录表单数据 - */ - async function authLogin( - params: Recordable, - onSuccess?: () => Promise | void, - ) { - // 异步处理用户登录操作并获取 accessToken - let userInfo: null | UserInfo = null; - try { - loginLoading.value = true; - const { accessToken } = await loginApi(params); - - // 如果成功获取到 accessToken - if (accessToken) { - // 将 accessToken 存储到 accessStore 中 - accessStore.setAccessToken(accessToken); - - // 获取用户信息并存储到 accessStore 中 - const [fetchUserInfoResult, accessCodes] = await Promise.all([ - fetchUserInfo(), - getAccessCodesApi(), - ]); - - userInfo = fetchUserInfoResult; - - userStore.setUserInfo(userInfo); - accessStore.setAccessCodes(accessCodes); - - if (accessStore.loginExpired) { - accessStore.setLoginExpired(false); - } else { - onSuccess - ? await onSuccess?.() - : await router.push( - userInfo.homePath || preferences.app.defaultHomePath, - ); - } - - if (userInfo?.realName) { - ElNotification({ - message: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, - title: $t('authentication.loginSuccess'), - type: 'success', - }); - } - } - } finally { - loginLoading.value = false; - } - - return { - userInfo, - }; - } - - async function logout(redirect: boolean = true) { - try { - await logoutApi(); - } catch { - // 不做任何处理 - } - resetAllStores(); - accessStore.setLoginExpired(false); - - // 回登录页带上当前路由地址 - await router.replace({ - path: LOGIN_PATH, - query: redirect - ? { - redirect: encodeURIComponent(router.currentRoute.value.fullPath), - } - : {}, - }); - } - - async function fetchUserInfo() { - let userInfo: null | UserInfo = null; - userInfo = await getUserInfoApi(); - userStore.setUserInfo(userInfo); - return userInfo; - } - - function $reset() { - loginLoading.value = false; - } - - return { - $reset, - authLogin, - fetchUserInfo, - loginLoading, - logout, - }; -}); diff --git a/apps/web-ele/src/store/index.ts b/apps/web-ele/src/store/index.ts deleted file mode 100644 index 269586ee..00000000 --- a/apps/web-ele/src/store/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth'; diff --git a/apps/web-ele/src/views/_core/README.md b/apps/web-ele/src/views/_core/README.md deleted file mode 100644 index 8248afe6..00000000 --- a/apps/web-ele/src/views/_core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# \_core - -此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。 diff --git a/apps/web-ele/src/views/_core/about/index.vue b/apps/web-ele/src/views/_core/about/index.vue deleted file mode 100644 index 0ee52433..00000000 --- a/apps/web-ele/src/views/_core/about/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/authentication/code-login.vue b/apps/web-ele/src/views/_core/authentication/code-login.vue deleted file mode 100644 index acfd1fd7..00000000 --- a/apps/web-ele/src/views/_core/authentication/code-login.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/authentication/forget-password.vue b/apps/web-ele/src/views/_core/authentication/forget-password.vue deleted file mode 100644 index fef0d427..00000000 --- a/apps/web-ele/src/views/_core/authentication/forget-password.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/authentication/login.vue b/apps/web-ele/src/views/_core/authentication/login.vue deleted file mode 100644 index 099e4c8c..00000000 --- a/apps/web-ele/src/views/_core/authentication/login.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/authentication/qrcode-login.vue b/apps/web-ele/src/views/_core/authentication/qrcode-login.vue deleted file mode 100644 index 23f5f2da..00000000 --- a/apps/web-ele/src/views/_core/authentication/qrcode-login.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/authentication/register.vue b/apps/web-ele/src/views/_core/authentication/register.vue deleted file mode 100644 index b1a5de72..00000000 --- a/apps/web-ele/src/views/_core/authentication/register.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/fallback/coming-soon.vue b/apps/web-ele/src/views/_core/fallback/coming-soon.vue deleted file mode 100644 index f394930f..00000000 --- a/apps/web-ele/src/views/_core/fallback/coming-soon.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/fallback/forbidden.vue b/apps/web-ele/src/views/_core/fallback/forbidden.vue deleted file mode 100644 index 8ea65fed..00000000 --- a/apps/web-ele/src/views/_core/fallback/forbidden.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/fallback/internal-error.vue b/apps/web-ele/src/views/_core/fallback/internal-error.vue deleted file mode 100644 index 819a47d5..00000000 --- a/apps/web-ele/src/views/_core/fallback/internal-error.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/fallback/not-found.vue b/apps/web-ele/src/views/_core/fallback/not-found.vue deleted file mode 100644 index 4d178e9c..00000000 --- a/apps/web-ele/src/views/_core/fallback/not-found.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/fallback/offline.vue b/apps/web-ele/src/views/_core/fallback/offline.vue deleted file mode 100644 index 5de4a88d..00000000 --- a/apps/web-ele/src/views/_core/fallback/offline.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/_core/profile/base-setting.vue b/apps/web-ele/src/views/_core/profile/base-setting.vue deleted file mode 100644 index aa8a4c26..00000000 --- a/apps/web-ele/src/views/_core/profile/base-setting.vue +++ /dev/null @@ -1,65 +0,0 @@ - - diff --git a/apps/web-ele/src/views/_core/profile/index.vue b/apps/web-ele/src/views/_core/profile/index.vue deleted file mode 100644 index 8740894e..00000000 --- a/apps/web-ele/src/views/_core/profile/index.vue +++ /dev/null @@ -1,49 +0,0 @@ - - diff --git a/apps/web-ele/src/views/_core/profile/notification-setting.vue b/apps/web-ele/src/views/_core/profile/notification-setting.vue deleted file mode 100644 index 324a4b39..00000000 --- a/apps/web-ele/src/views/_core/profile/notification-setting.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/apps/web-ele/src/views/_core/profile/password-setting.vue b/apps/web-ele/src/views/_core/profile/password-setting.vue deleted file mode 100644 index 4d80d74c..00000000 --- a/apps/web-ele/src/views/_core/profile/password-setting.vue +++ /dev/null @@ -1,66 +0,0 @@ - - diff --git a/apps/web-ele/src/views/_core/profile/security-setting.vue b/apps/web-ele/src/views/_core/profile/security-setting.vue deleted file mode 100644 index be30db58..00000000 --- a/apps/web-ele/src/views/_core/profile/security-setting.vue +++ /dev/null @@ -1,43 +0,0 @@ - - diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue deleted file mode 100644 index f1f0b232..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue deleted file mode 100644 index 190fb41f..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue deleted file mode 100644 index 02f50912..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue deleted file mode 100644 index 0915c7af..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue deleted file mode 100644 index 7e0f1013..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/analytics/index.vue b/apps/web-ele/src/views/dashboard/analytics/index.vue deleted file mode 100644 index 5e3d6d28..00000000 --- a/apps/web-ele/src/views/dashboard/analytics/index.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/dashboard/workspace/index.vue b/apps/web-ele/src/views/dashboard/workspace/index.vue deleted file mode 100644 index b95d6138..00000000 --- a/apps/web-ele/src/views/dashboard/workspace/index.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/demos/element/index.vue b/apps/web-ele/src/views/demos/element/index.vue deleted file mode 100644 index 0a7012d6..00000000 --- a/apps/web-ele/src/views/demos/element/index.vue +++ /dev/null @@ -1,117 +0,0 @@ - - - diff --git a/apps/web-ele/src/views/demos/form/basic.vue b/apps/web-ele/src/views/demos/form/basic.vue deleted file mode 100644 index 0ecab586..00000000 --- a/apps/web-ele/src/views/demos/form/basic.vue +++ /dev/null @@ -1,191 +0,0 @@ - - diff --git a/apps/web-ele/tailwind.config.mjs b/apps/web-ele/tailwind.config.mjs deleted file mode 100644 index f17f556f..00000000 --- a/apps/web-ele/tailwind.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config'; diff --git a/apps/web-ele/tsconfig.json b/apps/web-ele/tsconfig.json deleted file mode 100644 index 02c287fe..00000000 --- a/apps/web-ele/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/web-app.json", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "#/*": ["./src/*"] - } - }, - "references": [{ "path": "./tsconfig.node.json" }], - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] -} diff --git a/apps/web-ele/tsconfig.node.json b/apps/web-ele/tsconfig.node.json deleted file mode 100644 index c2f0d86c..00000000 --- a/apps/web-ele/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/node.json", - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "noEmit": false - }, - "include": ["vite.config.mts"] -} diff --git a/apps/web-ele/vite.config.mts b/apps/web-ele/vite.config.mts deleted file mode 100644 index 9f1e7235..00000000 --- a/apps/web-ele/vite.config.mts +++ /dev/null @@ -1,27 +0,0 @@ -import { defineConfig } from '@vben/vite-config'; - -import ElementPlus from 'unplugin-element-plus/vite'; - -export default defineConfig(async () => { - return { - application: {}, - vite: { - plugins: [ - ElementPlus({ - format: 'esm', - }), - ], - server: { - proxy: { - '/api': { - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), - // mock代理目标地址 - target: 'http://localhost:5320/api', - ws: true, - }, - }, - }, - }, - }; -}); diff --git a/apps/web-tdesign/.env b/apps/web-tdesign/.env deleted file mode 100644 index dae0149d..00000000 --- a/apps/web-tdesign/.env +++ /dev/null @@ -1,8 +0,0 @@ -# 应用标题 -VITE_APP_TITLE=Vben Admin Tdesign - -# 应用命名空间,用于缓存、store等功能的前缀,确保隔离 -VITE_APP_NAMESPACE=vben-web-tdesign - -# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 -VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key diff --git a/apps/web-tdesign/.env.analyze b/apps/web-tdesign/.env.analyze deleted file mode 100644 index ffafa8dd..00000000 --- a/apps/web-tdesign/.env.analyze +++ /dev/null @@ -1,7 +0,0 @@ -# public path -VITE_BASE=/ - -# Basic interface address SPA -VITE_GLOB_API_URL=/api - -VITE_VISUALIZER=true diff --git a/apps/web-tdesign/.env.development b/apps/web-tdesign/.env.development deleted file mode 100644 index f2b44428..00000000 --- a/apps/web-tdesign/.env.development +++ /dev/null @@ -1,16 +0,0 @@ -# 端口号 -VITE_PORT=5999 - -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=/api - -# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 -VITE_NITRO_MOCK=true - -# 是否打开 devtools,true 为打开,false 为关闭 -VITE_DEVTOOLS=false - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true diff --git a/apps/web-tdesign/.env.production b/apps/web-tdesign/.env.production deleted file mode 100644 index 5375847a..00000000 --- a/apps/web-tdesign/.env.production +++ /dev/null @@ -1,19 +0,0 @@ -VITE_BASE=/ - -# 接口地址 -VITE_GLOB_API_URL=https://mock-napi.vben.pro/api - -# 是否开启压缩,可以设置为 none, brotli, gzip -VITE_COMPRESS=none - -# 是否开启 PWA -VITE_PWA=false - -# vue-router 的模式 -VITE_ROUTER_HISTORY=hash - -# 是否注入全局loading -VITE_INJECT_APP_LOADING=true - -# 打包后是否生成dist.zip -VITE_ARCHIVER=true diff --git a/apps/web-tdesign/index.html b/apps/web-tdesign/index.html deleted file mode 100644 index 480eb84d..00000000 --- a/apps/web-tdesign/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - <%= VITE_APP_TITLE %> - - - - -
- - - diff --git a/apps/web-tdesign/package.json b/apps/web-tdesign/package.json deleted file mode 100644 index 9ff0bb7b..00000000 --- a/apps/web-tdesign/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "@vben/web-tdesign", - "version": "5.5.9", - "homepage": "https://vben.pro", - "bugs": "https://github.com/vbenjs/vue-vben-admin/issues", - "repository": { - "type": "git", - "url": "git+https://github.com/vbenjs/vue-vben-admin.git", - "directory": "apps/web-tdesign" - }, - "license": "MIT", - "author": { - "name": "vben", - "email": "ann.vben@gmail.com", - "url": "https://github.com/anncwb" - }, - "type": "module", - "scripts": { - "build": "pnpm vite build --mode production", - "build:analyze": "pnpm vite build --mode analyze", - "dev": "pnpm vite --mode development", - "preview": "vite preview", - "typecheck": "vue-tsc --noEmit --skipLibCheck" - }, - "imports": { - "#/*": "./src/*" - }, - "dependencies": { - "@vben/access": "workspace:*", - "@vben/common-ui": "workspace:*", - "@vben/constants": "workspace:*", - "@vben/hooks": "workspace:*", - "@vben/icons": "workspace:*", - "@vben/layouts": "workspace:*", - "@vben/locales": "workspace:*", - "@vben/plugins": "workspace:*", - "@vben/preferences": "workspace:*", - "@vben/request": "workspace:*", - "@vben/stores": "workspace:*", - "@vben/styles": "workspace:*", - "@vben/types": "workspace:*", - "@vben/utils": "workspace:*", - "@vueuse/core": "catalog:", - "dayjs": "catalog:", - "es-toolkit": "catalog:", - "pinia": "catalog:", - "tdesign-vue-next": "^1.17.1", - "vue": "catalog:", - "vue-router": "catalog:" - }, - "devDependencies": { - "@types/lodash-es": "^4.17.12" - } -} diff --git a/apps/web-tdesign/postcss.config.mjs b/apps/web-tdesign/postcss.config.mjs deleted file mode 100644 index 3d807045..00000000 --- a/apps/web-tdesign/postcss.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config/postcss'; diff --git a/apps/web-tdesign/public/favicon.ico b/apps/web-tdesign/public/favicon.ico deleted file mode 100644 index fcf9818e..00000000 Binary files a/apps/web-tdesign/public/favicon.ico and /dev/null differ diff --git a/apps/web-tdesign/src/adapter/component/index.ts b/apps/web-tdesign/src/adapter/component/index.ts deleted file mode 100644 index b7fc0547..00000000 --- a/apps/web-tdesign/src/adapter/component/index.ts +++ /dev/null @@ -1,229 +0,0 @@ -import type { Component } from 'vue'; - -import type { BaseFormComponentType } from '@vben/common-ui'; -import type { Recordable } from '@vben/types'; - -import { defineAsyncComponent, defineComponent, h, ref } from 'vue'; - -import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -import { notification } from '#/adapter/tdesign'; - -/** - * 通用组件共同的使用的基础组件,原先放在 adapter/form 内部,限制了使用范围,这里提取出来,方便其他地方使用 - * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, - */ - -const AutoComplete = defineAsyncComponent( - () => import('tdesign-vue-next/es/auto-complete'), -); -const Button = defineAsyncComponent(() => import('tdesign-vue-next/es/button')); -const Checkbox = defineAsyncComponent( - () => import('tdesign-vue-next/es/checkbox'), -); -const CheckboxGroup = defineAsyncComponent(() => - import('tdesign-vue-next/es/checkbox').then((res) => res.CheckboxGroup), -); -const DatePicker = defineAsyncComponent( - () => import('tdesign-vue-next/es/date-picker'), -); -const Divider = defineAsyncComponent( - () => import('tdesign-vue-next/es/divider'), -); -const Input = defineAsyncComponent(() => import('tdesign-vue-next/es/input')); -const InputNumber = defineAsyncComponent( - () => import('tdesign-vue-next/es/input-number'), -); -// const InputPassword = defineAsyncComponent(() => -// import('tdesign-vue-next/es/input').then((res) => res.InputPassword), -// ); -// const Mentions = defineAsyncComponent( -// () => import('tdesign-vue-next/es/mentions'), -// ); -const Radio = defineAsyncComponent(() => import('tdesign-vue-next/es/radio')); -const RadioGroup = defineAsyncComponent(() => - import('tdesign-vue-next/es/radio').then((res) => res.RadioGroup), -); -const RangePicker = defineAsyncComponent(() => - import('tdesign-vue-next/es/date-picker').then((res) => res.DateRangePicker), -); -const Rate = defineAsyncComponent(() => import('tdesign-vue-next/es/rate')); -const Select = defineAsyncComponent(() => import('tdesign-vue-next/es/select')); -const Space = defineAsyncComponent(() => import('tdesign-vue-next/es/space')); -const Switch = defineAsyncComponent(() => import('tdesign-vue-next/es/switch')); -const Textarea = defineAsyncComponent( - () => import('tdesign-vue-next/es/textarea'), -); -const TimePicker = defineAsyncComponent( - () => import('tdesign-vue-next/es/time-picker'), -); -const TreeSelect = defineAsyncComponent( - () => import('tdesign-vue-next/es/tree-select'), -); -const Upload = defineAsyncComponent(() => import('tdesign-vue-next/es/upload')); - -const withDefaultPlaceholder = ( - component: T, - type: 'input' | 'select', - componentProps: Recordable = {}, -) => { - return defineComponent({ - name: component.name, - inheritAttrs: false, - setup: (props: any, { attrs, expose, slots }) => { - const placeholder = - props?.placeholder || - attrs?.placeholder || - $t(`ui.placeholder.${type}`); - // 透传组件暴露的方法 - const innerRef = ref(); - expose( - new Proxy( - {}, - { - get: (_target, key) => innerRef.value?.[key], - has: (_target, key) => key in (innerRef.value || {}), - }, - ), - ); - return () => - h( - component, - { ...componentProps, placeholder, ...props, ...attrs, ref: innerRef }, - slots, - ); - }, - }); -}; - -// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 -export type ComponentType = - | 'ApiSelect' - | 'ApiTreeSelect' - | 'AutoComplete' - | 'Checkbox' - | 'CheckboxGroup' - | 'DatePicker' - | 'DefaultButton' - | 'Divider' - | 'IconPicker' - | 'Input' - | 'InputNumber' - // | 'InputPassword' - // | 'Mentions' - | 'PrimaryButton' - | 'Radio' - | 'RadioGroup' - | 'RangePicker' - | 'Rate' - | 'Select' - | 'Space' - | 'Switch' - | 'Textarea' - | 'TimePicker' - | 'TreeSelect' - | 'Upload' - | BaseFormComponentType; - -async function initComponentAdapter() { - const components: Partial> = { - // 如果你的组件体积比较大,可以使用异步加载 - // Button: () => - // import('xxx').then((res) => res.Button), - ApiSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiSelect', - }, - 'select', - { - component: Select, - loadingSlot: 'suffixIcon', - visibleEvent: 'onDropdownVisibleChange', - modelPropName: 'value', - }, - ), - ApiTreeSelect: withDefaultPlaceholder( - { - ...ApiComponent, - name: 'ApiTreeSelect', - }, - 'select', - { - component: TreeSelect, - fieldNames: { label: 'label', value: 'value', children: 'children' }, - loadingSlot: 'suffixIcon', - modelPropName: 'value', - optionsPropName: 'treeData', - visibleEvent: 'onVisibleChange', - }, - ), - AutoComplete, - Checkbox, - CheckboxGroup, - DatePicker, - // 自定义默认按钮 - DefaultButton: (props, { attrs, slots }) => { - return h(Button, { ...props, attrs, theme: 'default' }, slots); - }, - Divider, - IconPicker: withDefaultPlaceholder(IconPicker, 'select', { - iconSlot: 'addonAfter', - inputComponent: Input, - modelValueProp: 'value', - }), - Input: withDefaultPlaceholder(Input, 'input'), - InputNumber: withDefaultPlaceholder(InputNumber, 'input'), - // InputPassword: withDefaultPlaceholder(InputPassword, 'input'), - // Mentions: withDefaultPlaceholder(Mentions, 'input'), - // 自定义主要按钮 - PrimaryButton: (props, { attrs, slots }) => { - let ghost = false; - let variant = props.variant; - if (props.variant === 'ghost') { - ghost = true; - variant = 'base'; - } - return h( - Button, - { ...props, ghost, variant, attrs, theme: 'primary' }, - slots, - ); - }, - Radio, - RadioGroup, - RangePicker: (props, { attrs, slots }) => { - return h( - RangePicker, - { ...props, modelValue: props.modelValue ?? [], attrs }, - slots, - ); - }, - Rate, - Select: withDefaultPlaceholder(Select, 'select'), - Space, - Switch, - Textarea: withDefaultPlaceholder(Textarea, 'input'), - TimePicker, - TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'), - Upload, - }; - - // 将组件注册到全局共享状态中 - globalShareState.setComponents(components); - - // 定义全局共享状态中的消息提示 - globalShareState.defineMessage({ - // 复制成功消息提示 - copyPreferencesSuccess: (title, content) => { - notification.success({ - title, - content, - placement: 'bottom-right', - }); - }, - }); -} - -export { initComponentAdapter }; diff --git a/apps/web-tdesign/src/adapter/form.ts b/apps/web-tdesign/src/adapter/form.ts deleted file mode 100644 index ed094514..00000000 --- a/apps/web-tdesign/src/adapter/form.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { - VbenFormSchema as FormSchema, - VbenFormProps, -} from '@vben/common-ui'; - -import type { ComponentType } from './component'; - -import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui'; -import { $t } from '@vben/locales'; - -async function initSetupVbenForm() { - setupVbenForm({ - config: { - // tdesign组件库默认都是 v-model:value - baseModelPropName: 'value', - - // 一些组件是 v-model:checked 或者 v-model:fileList - modelPropNameMap: { - Checkbox: 'checked', - Radio: 'checked', - Switch: 'checked', - Upload: 'fileList', - }, - }, - defineRules: { - // 输入项目必填国际化适配 - required: (value, _params, ctx) => { - if (value === undefined || value === null || value.length === 0) { - return $t('ui.formRules.required', [ctx.label]); - } - return true; - }, - // 选择项目必填国际化适配 - selectRequired: (value, _params, ctx) => { - if (value === undefined || value === null) { - return $t('ui.formRules.selectRequired', [ctx.label]); - } - return true; - }, - }, - }); -} - -const useVbenForm = useForm; - -export { initSetupVbenForm, useVbenForm, z }; - -export type VbenFormSchema = FormSchema; -export type { VbenFormProps }; diff --git a/apps/web-tdesign/src/adapter/tdesign.ts b/apps/web-tdesign/src/adapter/tdesign.ts deleted file mode 100644 index 70c67601..00000000 --- a/apps/web-tdesign/src/adapter/tdesign.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { - DialogPlugin as dialog, - MessagePlugin as message, - NotifyPlugin as notification, -} from 'tdesign-vue-next'; diff --git a/apps/web-tdesign/src/adapter/vxe-table.ts b/apps/web-tdesign/src/adapter/vxe-table.ts deleted file mode 100644 index 43bd68af..00000000 --- a/apps/web-tdesign/src/adapter/vxe-table.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { VxeTableGridOptions } from '@vben/plugins/vxe-table'; - -import { h } from 'vue'; - -import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table'; - -import { Button, Image } from 'tdesign-vue-next'; - -import { useVbenForm } from './form'; - -setupVbenVxeTable({ - configVxeTable: (vxeUI) => { - vxeUI.setConfig({ - grid: { - align: 'center', - border: false, - columnConfig: { - resizable: true, - }, - minHeight: 180, - formConfig: { - // 全局禁用vxe-table的表单配置,使用formOptions - enabled: false, - }, - proxyConfig: { - autoLoad: true, - response: { - result: 'items', - total: 'total', - list: 'items', - }, - showActiveMsg: true, - showResponseMsg: false, - }, - round: true, - showOverflow: true, - size: 'small', - } as VxeTableGridOptions, - }); - - // 表格配置项可以用 cellRender: { name: 'CellImage' }, - vxeUI.renderer.add('CellImage', { - renderTableDefault(_renderOpts, params) { - const { column, row } = params; - return h(Image, { src: row[column.field] }); - }, - }); - - // 表格配置项可以用 cellRender: { name: 'CellLink' }, - vxeUI.renderer.add('CellLink', { - renderTableDefault(renderOpts) { - const { props } = renderOpts; - return h( - Button, - { size: 'small', theme: 'primary', variant: 'text' }, - { default: () => props?.text }, - ); - }, - }); - - // 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化 - // vxeUI.formats.add - }, - useVbenForm, -}); - -export { useVbenVxeGrid }; - -export type * from '@vben/plugins/vxe-table'; diff --git a/apps/web-tdesign/src/api/core/auth.ts b/apps/web-tdesign/src/api/core/auth.ts deleted file mode 100644 index 71d9f994..00000000 --- a/apps/web-tdesign/src/api/core/auth.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { baseRequestClient, requestClient } from '#/api/request'; - -export namespace AuthApi { - /** 登录接口参数 */ - export interface LoginParams { - password?: string; - username?: string; - } - - /** 登录接口返回值 */ - export interface LoginResult { - accessToken: string; - } - - export interface RefreshTokenResult { - data: string; - status: number; - } -} - -/** - * 登录 - */ -export async function loginApi(data: AuthApi.LoginParams) { - return requestClient.post('/auth/login', data); -} - -/** - * 刷新accessToken - */ -export async function refreshTokenApi() { - return baseRequestClient.post('/auth/refresh', { - withCredentials: true, - }); -} - -/** - * 退出登录 - */ -export async function logoutApi() { - return baseRequestClient.post('/auth/logout', { - withCredentials: true, - }); -} - -/** - * 获取用户权限码 - */ -export async function getAccessCodesApi() { - return requestClient.get('/auth/codes'); -} diff --git a/apps/web-tdesign/src/api/core/index.ts b/apps/web-tdesign/src/api/core/index.ts deleted file mode 100644 index 28a5aef4..00000000 --- a/apps/web-tdesign/src/api/core/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './auth'; -export * from './menu'; -export * from './user'; diff --git a/apps/web-tdesign/src/api/core/menu.ts b/apps/web-tdesign/src/api/core/menu.ts deleted file mode 100644 index 9ef60b11..00000000 --- a/apps/web-tdesign/src/api/core/menu.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { RouteRecordStringComponent } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户所有菜单 - */ -export async function getAllMenusApi() { - return requestClient.get('/menu/all'); -} diff --git a/apps/web-tdesign/src/api/core/user.ts b/apps/web-tdesign/src/api/core/user.ts deleted file mode 100644 index 7e28ea84..00000000 --- a/apps/web-tdesign/src/api/core/user.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UserInfo } from '@vben/types'; - -import { requestClient } from '#/api/request'; - -/** - * 获取用户信息 - */ -export async function getUserInfoApi() { - return requestClient.get('/user/info'); -} diff --git a/apps/web-tdesign/src/api/index.ts b/apps/web-tdesign/src/api/index.ts deleted file mode 100644 index 4b0e0413..00000000 --- a/apps/web-tdesign/src/api/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './core'; diff --git a/apps/web-tdesign/src/api/request.ts b/apps/web-tdesign/src/api/request.ts deleted file mode 100644 index 86b181d3..00000000 --- a/apps/web-tdesign/src/api/request.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 该文件可自行根据业务逻辑进行调整 - */ -import type { RequestClientOptions } from '@vben/request'; - -import { useAppConfig } from '@vben/hooks'; -import { preferences } from '@vben/preferences'; -import { - authenticateResponseInterceptor, - defaultResponseInterceptor, - errorMessageResponseInterceptor, - RequestClient, -} from '@vben/request'; -import { useAccessStore } from '@vben/stores'; - -import { message } from '#/adapter/tdesign'; -import { useAuthStore } from '#/store'; - -import { refreshTokenApi } from './core'; - -const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD); - -function createRequestClient(baseURL: string, options?: RequestClientOptions) { - const client = new RequestClient({ - ...options, - baseURL, - }); - - /** - * 重新认证逻辑 - */ - async function doReAuthenticate() { - console.warn('Access token or refresh token is invalid or expired. '); - const accessStore = useAccessStore(); - const authStore = useAuthStore(); - accessStore.setAccessToken(null); - if ( - preferences.app.loginExpiredMode === 'modal' && - accessStore.isAccessChecked - ) { - accessStore.setLoginExpired(true); - } else { - await authStore.logout(); - } - } - - /** - * 刷新token逻辑 - */ - async function doRefreshToken() { - const accessStore = useAccessStore(); - const resp = await refreshTokenApi(); - const newToken = resp.data; - accessStore.setAccessToken(newToken); - return newToken; - } - - function formatToken(token: null | string) { - return token ? `Bearer ${token}` : null; - } - - // 请求头处理 - client.addRequestInterceptor({ - fulfilled: async (config) => { - const accessStore = useAccessStore(); - - config.headers.Authorization = formatToken(accessStore.accessToken); - config.headers['Accept-Language'] = preferences.app.locale; - return config; - }, - }); - - // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); - - // token过期的处理 - client.addResponseInterceptor( - authenticateResponseInterceptor({ - client, - doReAuthenticate, - doRefreshToken, - enableRefreshToken: preferences.app.enableRefreshToken, - formatToken, - }), - ); - - // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里 - client.addResponseInterceptor( - errorMessageResponseInterceptor((msg: string, error) => { - // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg - // 当前mock接口返回的错误字段是 error 或者 message - const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; - // 如果没有错误信息,则会根据状态码进行提示 - message.error(errorMessage || msg); - }), - ); - - return client; -} - -export const requestClient = createRequestClient(apiURL, { - responseReturn: 'data', -}); - -export const baseRequestClient = new RequestClient({ baseURL: apiURL }); diff --git a/apps/web-tdesign/src/app.vue b/apps/web-tdesign/src/app.vue deleted file mode 100644 index 1626c9d3..00000000 --- a/apps/web-tdesign/src/app.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/bootstrap.ts b/apps/web-tdesign/src/bootstrap.ts deleted file mode 100644 index 4ed74cc5..00000000 --- a/apps/web-tdesign/src/bootstrap.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createApp, watchEffect } from 'vue'; - -import { registerAccessDirective } from '@vben/access'; -import { registerLoadingDirective } from '@vben/common-ui/es/loading'; -import { preferences } from '@vben/preferences'; -import { initStores } from '@vben/stores'; -import '@vben/styles'; -// import '@vben/styles/antd'; -// 引入组件库的少量全局样式变量 -import 'tdesign-vue-next/es/style/index.css'; -import { useTitle } from '@vueuse/core'; - -import { $t, setupI18n } from '#/locales'; - -import { initComponentAdapter } from './adapter/component'; -import { initSetupVbenForm } from './adapter/form'; -import App from './app.vue'; -import { router } from './router'; - -async function bootstrap(namespace: string) { - // 初始化组件适配器 - await initComponentAdapter(); - - // 初始化表单组件 - await initSetupVbenForm(); - - // // 设置弹窗的默认配置 - // setDefaultModalProps({ - // fullscreenButton: false, - // }); - // // 设置抽屉的默认配置 - // setDefaultDrawerProps({ - // zIndex: 1020, - // }); - - const app = createApp(App); - - // 注册v-loading指令 - registerLoadingDirective(app, { - loading: 'loading', // 在这里可以自定义指令名称,也可以明确提供false表示不注册这个指令 - spinning: 'spinning', - }); - - // 国际化 i18n 配置 - await setupI18n(app); - - // 配置 pinia-tore - await initStores(app, { namespace }); - - // 安装权限指令 - registerAccessDirective(app); - - // 初始化 tippy - const { initTippy } = await import('@vben/common-ui/es/tippy'); - initTippy(app); - - // 配置路由及路由守卫 - app.use(router); - - // 配置Motion插件 - const { MotionPlugin } = await import('@vben/plugins/motion'); - app.use(MotionPlugin); - - // 动态更新标题 - watchEffect(() => { - if (preferences.app.dynamicTitle) { - const routeTitle = router.currentRoute.value.meta?.title; - const pageTitle = - (routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name; - useTitle(pageTitle); - } - }); - - app.mount('#app'); -} - -export { bootstrap }; diff --git a/apps/web-tdesign/src/layouts/auth.vue b/apps/web-tdesign/src/layouts/auth.vue deleted file mode 100644 index 18d415bc..00000000 --- a/apps/web-tdesign/src/layouts/auth.vue +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/layouts/basic.vue b/apps/web-tdesign/src/layouts/basic.vue deleted file mode 100644 index 2226c68a..00000000 --- a/apps/web-tdesign/src/layouts/basic.vue +++ /dev/null @@ -1,206 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/layouts/index.ts b/apps/web-tdesign/src/layouts/index.ts deleted file mode 100644 index a4320780..00000000 --- a/apps/web-tdesign/src/layouts/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -const BasicLayout = () => import('./basic.vue'); -const AuthPageLayout = () => import('./auth.vue'); - -const IFrameView = () => import('@vben/layouts').then((m) => m.IFrameView); - -export { AuthPageLayout, BasicLayout, IFrameView }; diff --git a/apps/web-tdesign/src/locales/README.md b/apps/web-tdesign/src/locales/README.md deleted file mode 100644 index 7b451032..00000000 --- a/apps/web-tdesign/src/locales/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# locale - -每个app使用的国际化可能不同,这里用于扩展国际化的功能,例如扩展 dayjs、antd组件库的多语言切换,以及app本身的国际化文件。 diff --git a/apps/web-tdesign/src/locales/index.ts b/apps/web-tdesign/src/locales/index.ts deleted file mode 100644 index 6d98579a..00000000 --- a/apps/web-tdesign/src/locales/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { App } from 'vue'; - -import type { LocaleSetupOptions, SupportedLanguagesType } from '@vben/locales'; - -import { - $t, - setupI18n as coreSetup, - loadLocalesMapFromDir, -} from '@vben/locales'; -import { preferences } from '@vben/preferences'; - -import dayjs from 'dayjs'; - -const modules = import.meta.glob('./langs/**/*.json'); - -const localesMap = loadLocalesMapFromDir( - /\.\/langs\/([^/]+)\/(.*)\.json$/, - modules, -); -/** - * 加载应用特有的语言包 - * 这里也可以改造为从服务端获取翻译数据 - * @param lang - */ -async function loadMessages(lang: SupportedLanguagesType) { - const [appLocaleMessages] = await Promise.all([ - localesMap[lang]?.(), - loadThirdPartyMessage(lang), - ]); - return appLocaleMessages?.default; -} - -/** - * 加载第三方组件库的语言包 - * @param lang - */ -async function loadThirdPartyMessage(lang: SupportedLanguagesType) { - await loadDayjsLocale(lang); -} - -/** - * 加载dayjs的语言包 - * @param lang - */ -async function loadDayjsLocale(lang: SupportedLanguagesType) { - let locale; - switch (lang) { - case 'en-US': { - locale = await import('dayjs/locale/en'); - break; - } - case 'zh-CN': { - locale = await import('dayjs/locale/zh-cn'); - break; - } - // 默认使用英语 - default: { - locale = await import('dayjs/locale/en'); - } - } - if (locale) { - dayjs.locale(locale); - } else { - console.error(`Failed to load dayjs locale for ${lang}`); - } -} - -async function setupI18n(app: App, options: LocaleSetupOptions = {}) { - await coreSetup(app, { - defaultLocale: preferences.app.locale, - loadMessages, - missingWarn: !import.meta.env.PROD, - ...options, - }); -} - -export { $t, setupI18n }; diff --git a/apps/web-tdesign/src/locales/langs/en-US/demos.json b/apps/web-tdesign/src/locales/langs/en-US/demos.json deleted file mode 100644 index e7bcea12..00000000 --- a/apps/web-tdesign/src/locales/langs/en-US/demos.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Demos", - "tdesign": "TDesign Vue", - "vben": { - "title": "Project", - "about": "About", - "document": "Document", - "antdv": "Ant Design Vue Version", - "naive-ui": "Naive UI Version", - "element-plus": "Element Plus Version" - } -} diff --git a/apps/web-tdesign/src/locales/langs/en-US/page.json b/apps/web-tdesign/src/locales/langs/en-US/page.json deleted file mode 100644 index 39f1641c..00000000 --- a/apps/web-tdesign/src/locales/langs/en-US/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "Login", - "register": "Register", - "codeLogin": "Code Login", - "qrcodeLogin": "Qr Code Login", - "forgetPassword": "Forget Password", - "profile": "Profile" - }, - "dashboard": { - "title": "Dashboard", - "analytics": "Analytics", - "workspace": "Workspace" - } -} diff --git a/apps/web-tdesign/src/locales/langs/zh-CN/demos.json b/apps/web-tdesign/src/locales/langs/zh-CN/demos.json deleted file mode 100644 index 843a1f30..00000000 --- a/apps/web-tdesign/src/locales/langs/zh-CN/demos.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "演示", - "tdesign": "TDesign Vue", - "vben": { - "title": "项目", - "about": "关于", - "document": "文档", - "antdv": "Ant Design Vue 版本", - "naive-ui": "Naive UI 版本", - "element-plus": "Element Plus 版本" - } -} diff --git a/apps/web-tdesign/src/locales/langs/zh-CN/page.json b/apps/web-tdesign/src/locales/langs/zh-CN/page.json deleted file mode 100644 index 2192d1d5..00000000 --- a/apps/web-tdesign/src/locales/langs/zh-CN/page.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "auth": { - "login": "登录", - "register": "注册", - "codeLogin": "验证码登录", - "qrcodeLogin": "二维码登录", - "forgetPassword": "忘记密码", - "profile": "个人中心" - }, - "dashboard": { - "title": "概览", - "analytics": "分析页", - "workspace": "工作台" - } -} diff --git a/apps/web-tdesign/src/main.ts b/apps/web-tdesign/src/main.ts deleted file mode 100644 index 5d728a02..00000000 --- a/apps/web-tdesign/src/main.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { initPreferences } from '@vben/preferences'; -import { unmountGlobalLoading } from '@vben/utils'; - -import { overridesPreferences } from './preferences'; - -/** - * 应用初始化完成之后再进行页面加载渲染 - */ -async function initApplication() { - // name用于指定项目唯一标识 - // 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据 - const env = import.meta.env.PROD ? 'prod' : 'dev'; - const appVersion = import.meta.env.VITE_APP_VERSION; - const namespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`; - - // app偏好设置初始化 - await initPreferences({ - namespace, - overrides: overridesPreferences, - }); - - // 启动应用并挂载 - // vue应用主要逻辑及视图 - const { bootstrap } = await import('./bootstrap'); - await bootstrap(namespace); - - // 移除并销毁loading - unmountGlobalLoading(); -} - -initApplication(); diff --git a/apps/web-tdesign/src/preferences.ts b/apps/web-tdesign/src/preferences.ts deleted file mode 100644 index b2e9ace4..00000000 --- a/apps/web-tdesign/src/preferences.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { defineOverridesPreferences } from '@vben/preferences'; - -/** - * @description 项目配置文件 - * 只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置 - * !!! 更改配置后请清空缓存,否则可能不生效 - */ -export const overridesPreferences = defineOverridesPreferences({ - // overrides - app: { - name: import.meta.env.VITE_APP_TITLE, - }, -}); diff --git a/apps/web-tdesign/src/router/access.ts b/apps/web-tdesign/src/router/access.ts deleted file mode 100644 index 08cb4b0b..00000000 --- a/apps/web-tdesign/src/router/access.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { - ComponentRecordType, - GenerateMenuAndRoutesOptions, -} from '@vben/types'; - -import { generateAccessible } from '@vben/access'; -import { preferences } from '@vben/preferences'; - -import { message } from '#/adapter/tdesign'; -import { getAllMenusApi } from '#/api'; -import { BasicLayout, IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue'); - -async function generateAccess(options: GenerateMenuAndRoutesOptions) { - const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue'); - - const layoutMap: ComponentRecordType = { - BasicLayout, - IFrameView, - }; - - return await generateAccessible(preferences.app.accessMode, { - ...options, - fetchMenuListAsync: async () => { - message.loading({ - content: `${$t('common.loadingMenu')}...`, - duration: 1500, - }); - return await getAllMenusApi(); - }, - // 可以指定没有权限跳转403页面 - forbiddenComponent, - // 如果 route.meta.menuVisibleWithForbidden = true - layoutMap, - pageMap, - }); -} - -export { generateAccess }; diff --git a/apps/web-tdesign/src/router/guard.ts b/apps/web-tdesign/src/router/guard.ts deleted file mode 100644 index a1ad6d88..00000000 --- a/apps/web-tdesign/src/router/guard.ts +++ /dev/null @@ -1,133 +0,0 @@ -import type { Router } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { useAccessStore, useUserStore } from '@vben/stores'; -import { startProgress, stopProgress } from '@vben/utils'; - -import { accessRoutes, coreRouteNames } from '#/router/routes'; -import { useAuthStore } from '#/store'; - -import { generateAccess } from './access'; - -/** - * 通用守卫配置 - * @param router - */ -function setupCommonGuard(router: Router) { - // 记录已经加载的页面 - const loadedPaths = new Set(); - - router.beforeEach((to) => { - to.meta.loaded = loadedPaths.has(to.path); - - // 页面加载进度条 - if (!to.meta.loaded && preferences.transition.progress) { - startProgress(); - } - return true; - }); - - router.afterEach((to) => { - // 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行 - - loadedPaths.add(to.path); - - // 关闭页面加载进度条 - if (preferences.transition.progress) { - stopProgress(); - } - }); -} - -/** - * 权限访问守卫配置 - * @param router - */ -function setupAccessGuard(router: Router) { - router.beforeEach(async (to, from) => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const authStore = useAuthStore(); - - // 基本路由,这些路由不需要进入权限拦截 - if (coreRouteNames.includes(to.name as string)) { - if (to.path === LOGIN_PATH && accessStore.accessToken) { - return decodeURIComponent( - (to.query?.redirect as string) || - userStore.userInfo?.homePath || - preferences.app.defaultHomePath, - ); - } - return true; - } - - // accessToken 检查 - if (!accessStore.accessToken) { - // 明确声明忽略权限访问权限,则可以访问 - if (to.meta.ignoreAccess) { - return true; - } - - // 没有访问权限,跳转登录页面 - if (to.fullPath !== LOGIN_PATH) { - return { - path: LOGIN_PATH, - // 如不需要,直接删除 query - query: - to.fullPath === preferences.app.defaultHomePath - ? {} - : { redirect: encodeURIComponent(to.fullPath) }, - // 携带当前跳转的页面,登录后重新跳转该页面 - replace: true, - }; - } - return to; - } - - // 是否已经生成过动态路由 - if (accessStore.isAccessChecked) { - return true; - } - - // 生成路由表 - // 当前登录用户拥有的角色标识列表 - const userInfo = userStore.userInfo || (await authStore.fetchUserInfo()); - const userRoles = userInfo.roles ?? []; - - // 生成菜单和路由 - const { accessibleMenus, accessibleRoutes } = await generateAccess({ - roles: userRoles, - router, - // 则会在菜单中显示,但是访问会被重定向到403 - routes: accessRoutes, - }); - - // 保存菜单信息和路由信息 - accessStore.setAccessMenus(accessibleMenus); - accessStore.setAccessRoutes(accessibleRoutes); - accessStore.setIsAccessChecked(true); - const redirectPath = (from.query.redirect ?? - (to.path === preferences.app.defaultHomePath - ? userInfo.homePath || preferences.app.defaultHomePath - : to.fullPath)) as string; - - return { - ...router.resolve(decodeURIComponent(redirectPath)), - replace: true, - }; - }); -} - -/** - * 项目守卫配置 - * @param router - */ -function createRouterGuard(router: Router) { - /** 通用 */ - setupCommonGuard(router); - /** 权限访问 */ - setupAccessGuard(router); -} - -export { createRouterGuard }; diff --git a/apps/web-tdesign/src/router/index.ts b/apps/web-tdesign/src/router/index.ts deleted file mode 100644 index 48402303..00000000 --- a/apps/web-tdesign/src/router/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - createRouter, - createWebHashHistory, - createWebHistory, -} from 'vue-router'; - -import { resetStaticRoutes } from '@vben/utils'; - -import { createRouterGuard } from './guard'; -import { routes } from './routes'; - -/** - * @zh_CN 创建vue-router实例 - */ -const router = createRouter({ - history: - import.meta.env.VITE_ROUTER_HISTORY === 'hash' - ? createWebHashHistory(import.meta.env.VITE_BASE) - : createWebHistory(import.meta.env.VITE_BASE), - // 应该添加到路由的初始路由列表。 - routes, - scrollBehavior: (to, _from, savedPosition) => { - if (savedPosition) { - return savedPosition; - } - return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 }; - }, - // 是否应该禁止尾部斜杠。 - // strict: true, -}); - -const resetRoutes = () => resetStaticRoutes(router, routes); - -// 创建路由守卫 -createRouterGuard(router); - -export { resetRoutes, router }; diff --git a/apps/web-tdesign/src/router/routes/core.ts b/apps/web-tdesign/src/router/routes/core.ts deleted file mode 100644 index 949b0b65..00000000 --- a/apps/web-tdesign/src/router/routes/core.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; - -import { $t } from '#/locales'; - -const BasicLayout = () => import('#/layouts/basic.vue'); -const AuthPageLayout = () => import('#/layouts/auth.vue'); -/** 全局404页面 */ -const fallbackNotFoundRoute: RouteRecordRaw = { - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - hideInBreadcrumb: true, - hideInMenu: true, - hideInTab: true, - title: '404', - }, - name: 'FallbackNotFound', - path: '/:path(.*)*', -}; - -/** 基本路由,这些路由是必须存在的 */ -const coreRoutes: RouteRecordRaw[] = [ - /** - * 根路由 - * 使用基础布局,作为所有页面的父级容器,子级就不必配置BasicLayout。 - * 此路由必须存在,且不应修改 - */ - { - component: BasicLayout, - meta: { - hideInBreadcrumb: true, - title: 'Root', - }, - name: 'Root', - path: '/', - redirect: preferences.app.defaultHomePath, - children: [], - }, - { - component: AuthPageLayout, - meta: { - hideInTab: true, - title: 'Authentication', - }, - name: 'Authentication', - path: '/auth', - redirect: LOGIN_PATH, - children: [ - { - name: 'Login', - path: 'login', - component: () => import('#/views/_core/authentication/login.vue'), - meta: { - title: $t('page.auth.login'), - }, - }, - { - name: 'CodeLogin', - path: 'code-login', - component: () => import('#/views/_core/authentication/code-login.vue'), - meta: { - title: $t('page.auth.codeLogin'), - }, - }, - { - name: 'QrCodeLogin', - path: 'qrcode-login', - component: () => - import('#/views/_core/authentication/qrcode-login.vue'), - meta: { - title: $t('page.auth.qrcodeLogin'), - }, - }, - { - name: 'ForgetPassword', - path: 'forget-password', - component: () => - import('#/views/_core/authentication/forget-password.vue'), - meta: { - title: $t('page.auth.forgetPassword'), - }, - }, - { - name: 'Register', - path: 'register', - component: () => import('#/views/_core/authentication/register.vue'), - meta: { - title: $t('page.auth.register'), - }, - }, - ], - }, -]; - -export { coreRoutes, fallbackNotFoundRoute }; diff --git a/apps/web-tdesign/src/router/routes/index.ts b/apps/web-tdesign/src/router/routes/index.ts deleted file mode 100644 index e6fb1440..00000000 --- a/apps/web-tdesign/src/router/routes/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { mergeRouteModules, traverseTreeValues } from '@vben/utils'; - -import { coreRoutes, fallbackNotFoundRoute } from './core'; - -const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', { - eager: true, -}); - -// 有需要可以自行打开注释,并创建文件夹 -// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true }); -// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true }); - -/** 动态路由 */ -const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles); - -/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */ -// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles); -// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles); -const staticRoutes: RouteRecordRaw[] = []; -const externalRoutes: RouteRecordRaw[] = []; - -/** 路由列表,由基本路由、外部路由和404兜底路由组成 - * 无需走权限验证(会一直显示在菜单中) */ -const routes: RouteRecordRaw[] = [ - ...coreRoutes, - ...externalRoutes, - fallbackNotFoundRoute, -]; - -/** 基本路由列表,这些路由不需要进入权限拦截 */ -const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name); - -/** 有权限校验的路由列表,包含动态路由和静态路由 */ -const accessRoutes = [...dynamicRoutes, ...staticRoutes]; -export { accessRoutes, coreRouteNames, routes }; diff --git a/apps/web-tdesign/src/router/routes/modules/dashboard.ts b/apps/web-tdesign/src/router/routes/modules/dashboard.ts deleted file mode 100644 index 5254dc65..00000000 --- a/apps/web-tdesign/src/router/routes/modules/dashboard.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'lucide:layout-dashboard', - order: -1, - title: $t('page.dashboard.title'), - }, - name: 'Dashboard', - path: '/dashboard', - children: [ - { - name: 'Analytics', - path: '/analytics', - component: () => import('#/views/dashboard/analytics/index.vue'), - meta: { - affixTab: true, - icon: 'lucide:area-chart', - title: $t('page.dashboard.analytics'), - }, - }, - { - name: 'Workspace', - path: '/workspace', - component: () => import('#/views/dashboard/workspace/index.vue'), - meta: { - icon: 'carbon:workspace', - title: $t('page.dashboard.workspace'), - }, - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-tdesign/src/router/routes/modules/demos.ts b/apps/web-tdesign/src/router/routes/modules/demos.ts deleted file mode 100644 index 9ce8ec99..00000000 --- a/apps/web-tdesign/src/router/routes/modules/demos.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - icon: 'ic:baseline-view-in-ar', - keepAlive: true, - order: 1000, - title: $t('demos.title'), - }, - name: 'Demos', - path: '/demos', - children: [ - { - meta: { - title: $t('demos.tdesign'), - }, - name: 'TDesignDemos', - path: '/demos/tdesign', - component: () => import('#/views/demos/tdesign/index.vue'), - }, - ], - }, -]; - -export default routes; diff --git a/apps/web-tdesign/src/router/routes/modules/vben.ts b/apps/web-tdesign/src/router/routes/modules/vben.ts deleted file mode 100644 index a5f0aa4d..00000000 --- a/apps/web-tdesign/src/router/routes/modules/vben.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { RouteRecordRaw } from 'vue-router'; - -import { - VBEN_ANT_PREVIEW_URL, - VBEN_DOC_URL, - VBEN_ELE_PREVIEW_URL, - VBEN_GITHUB_URL, - VBEN_LOGO_URL, - VBEN_NAIVE_PREVIEW_URL, -} from '@vben/constants'; -import { SvgAntdvLogoIcon } from '@vben/icons'; - -import { IFrameView } from '#/layouts'; -import { $t } from '#/locales'; - -const routes: RouteRecordRaw[] = [ - { - meta: { - badgeType: 'dot', - icon: VBEN_LOGO_URL, - order: 9998, - title: $t('demos.vben.title'), - }, - name: 'VbenProject', - path: '/vben-admin', - children: [ - { - name: 'VbenDocument', - path: '/vben-admin/document', - component: IFrameView, - meta: { - icon: 'lucide:book-open-text', - link: VBEN_DOC_URL, - title: $t('demos.vben.document'), - }, - }, - { - name: 'VbenGithub', - path: '/vben-admin/github', - component: IFrameView, - meta: { - icon: 'mdi:github', - link: VBEN_GITHUB_URL, - title: 'Github', - }, - }, - { - name: 'VbenNaive', - path: '/vben-admin/naive', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:naiveui', - link: VBEN_NAIVE_PREVIEW_URL, - title: $t('demos.vben.naive-ui'), - }, - }, - { - name: 'VbenAntdv', - path: '/vben-admin/antdv', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: SvgAntdvLogoIcon, - link: VBEN_ANT_PREVIEW_URL, - title: $t('demos.vben.antdv'), - }, - }, - { - name: 'VbenElementPlus', - path: '/vben-admin/ele', - component: IFrameView, - meta: { - badgeType: 'dot', - icon: 'logos:element', - link: VBEN_ELE_PREVIEW_URL, - title: $t('demos.vben.element-plus'), - }, - }, - ], - }, - { - name: 'VbenAbout', - path: '/vben-admin/about', - component: () => import('#/views/_core/about/index.vue'), - meta: { - icon: 'lucide:copyright', - title: $t('demos.vben.about'), - order: 9999, - }, - }, - { - name: 'Profile', - path: '/profile', - component: () => import('#/views/_core/profile/index.vue'), - meta: { - icon: 'lucide:user', - hideInMenu: true, - title: $t('page.auth.profile'), - }, - }, -]; - -export default routes; diff --git a/apps/web-tdesign/src/store/auth.ts b/apps/web-tdesign/src/store/auth.ts deleted file mode 100644 index b3b4b749..00000000 --- a/apps/web-tdesign/src/store/auth.ts +++ /dev/null @@ -1,117 +0,0 @@ -import type { Recordable, UserInfo } from '@vben/types'; - -import { ref } from 'vue'; -import { useRouter } from 'vue-router'; - -import { LOGIN_PATH } from '@vben/constants'; -import { preferences } from '@vben/preferences'; -import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores'; - -import { defineStore } from 'pinia'; - -import { notification } from '#/adapter/tdesign'; -import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api'; -import { $t } from '#/locales'; - -export const useAuthStore = defineStore('auth', () => { - const accessStore = useAccessStore(); - const userStore = useUserStore(); - const router = useRouter(); - - const loginLoading = ref(false); - - /** - * 异步处理登录操作 - * Asynchronously handle the login process - * @param params 登录表单数据 - */ - async function authLogin( - params: Recordable, - onSuccess?: () => Promise | void, - ) { - // 异步处理用户登录操作并获取 accessToken - let userInfo: null | UserInfo = null; - try { - loginLoading.value = true; - const { accessToken } = await loginApi(params); - - // 如果成功获取到 accessToken - if (accessToken) { - accessStore.setAccessToken(accessToken); - // 获取用户信息并存储到 accessStore 中 - const [fetchUserInfoResult, accessCodes] = await Promise.all([ - fetchUserInfo(), - getAccessCodesApi(), - ]); - - userInfo = fetchUserInfoResult; - - userStore.setUserInfo(userInfo); - accessStore.setAccessCodes(accessCodes); - - if (accessStore.loginExpired) { - accessStore.setLoginExpired(false); - } else { - onSuccess - ? await onSuccess?.() - : await router.push( - userInfo.homePath || preferences.app.defaultHomePath, - ); - } - - if (userInfo?.realName) { - notification.success({ - title: $t('authentication.loginSuccess'), - content: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`, - duration: 3000, - }); - } - } - } finally { - loginLoading.value = false; - } - - return { - userInfo, - }; - } - - async function logout(redirect: boolean = true) { - try { - await logoutApi(); - } catch { - // 不做任何处理 - } - resetAllStores(); - accessStore.setLoginExpired(false); - - // 回登录页带上当前路由地址 - await router.replace({ - path: LOGIN_PATH, - query: redirect - ? { - redirect: encodeURIComponent(router.currentRoute.value.fullPath), - } - : {}, - }); - } - - async function fetchUserInfo() { - let userInfo: null | UserInfo = null; - userInfo = await getUserInfoApi(); - userStore.setUserInfo(userInfo); - return userInfo; - } - - function $reset() { - loginLoading.value = false; - } - - return { - $reset, - authLogin, - fetchUserInfo, - loginLoading, - logout, - }; -}); diff --git a/apps/web-tdesign/src/store/index.ts b/apps/web-tdesign/src/store/index.ts deleted file mode 100644 index 269586ee..00000000 --- a/apps/web-tdesign/src/store/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth'; diff --git a/apps/web-tdesign/src/views/_core/README.md b/apps/web-tdesign/src/views/_core/README.md deleted file mode 100644 index 8248afe6..00000000 --- a/apps/web-tdesign/src/views/_core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# \_core - -此目录包含应用程序正常运行所需的基本视图。这些视图是应用程序布局中使用的视图。 diff --git a/apps/web-tdesign/src/views/_core/about/index.vue b/apps/web-tdesign/src/views/_core/about/index.vue deleted file mode 100644 index 0ee52433..00000000 --- a/apps/web-tdesign/src/views/_core/about/index.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/authentication/code-login.vue b/apps/web-tdesign/src/views/_core/authentication/code-login.vue deleted file mode 100644 index acfd1fd7..00000000 --- a/apps/web-tdesign/src/views/_core/authentication/code-login.vue +++ /dev/null @@ -1,69 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/authentication/forget-password.vue b/apps/web-tdesign/src/views/_core/authentication/forget-password.vue deleted file mode 100644 index fef0d427..00000000 --- a/apps/web-tdesign/src/views/_core/authentication/forget-password.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/authentication/login.vue b/apps/web-tdesign/src/views/_core/authentication/login.vue deleted file mode 100644 index 89af0c27..00000000 --- a/apps/web-tdesign/src/views/_core/authentication/login.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue b/apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue deleted file mode 100644 index 23f5f2da..00000000 --- a/apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/authentication/register.vue b/apps/web-tdesign/src/views/_core/authentication/register.vue deleted file mode 100644 index 1a80ff51..00000000 --- a/apps/web-tdesign/src/views/_core/authentication/register.vue +++ /dev/null @@ -1,96 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/fallback/coming-soon.vue b/apps/web-tdesign/src/views/_core/fallback/coming-soon.vue deleted file mode 100644 index f394930f..00000000 --- a/apps/web-tdesign/src/views/_core/fallback/coming-soon.vue +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/fallback/forbidden.vue b/apps/web-tdesign/src/views/_core/fallback/forbidden.vue deleted file mode 100644 index 8ea65fed..00000000 --- a/apps/web-tdesign/src/views/_core/fallback/forbidden.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/fallback/internal-error.vue b/apps/web-tdesign/src/views/_core/fallback/internal-error.vue deleted file mode 100644 index 819a47d5..00000000 --- a/apps/web-tdesign/src/views/_core/fallback/internal-error.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/fallback/not-found.vue b/apps/web-tdesign/src/views/_core/fallback/not-found.vue deleted file mode 100644 index 4d178e9c..00000000 --- a/apps/web-tdesign/src/views/_core/fallback/not-found.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/fallback/offline.vue b/apps/web-tdesign/src/views/_core/fallback/offline.vue deleted file mode 100644 index 5de4a88d..00000000 --- a/apps/web-tdesign/src/views/_core/fallback/offline.vue +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/_core/profile/base-setting.vue b/apps/web-tdesign/src/views/_core/profile/base-setting.vue deleted file mode 100644 index aa8a4c26..00000000 --- a/apps/web-tdesign/src/views/_core/profile/base-setting.vue +++ /dev/null @@ -1,65 +0,0 @@ - - diff --git a/apps/web-tdesign/src/views/_core/profile/index.vue b/apps/web-tdesign/src/views/_core/profile/index.vue deleted file mode 100644 index 8740894e..00000000 --- a/apps/web-tdesign/src/views/_core/profile/index.vue +++ /dev/null @@ -1,49 +0,0 @@ - - diff --git a/apps/web-tdesign/src/views/_core/profile/notification-setting.vue b/apps/web-tdesign/src/views/_core/profile/notification-setting.vue deleted file mode 100644 index 324a4b39..00000000 --- a/apps/web-tdesign/src/views/_core/profile/notification-setting.vue +++ /dev/null @@ -1,31 +0,0 @@ - - diff --git a/apps/web-tdesign/src/views/_core/profile/password-setting.vue b/apps/web-tdesign/src/views/_core/profile/password-setting.vue deleted file mode 100644 index 7e1c0f08..00000000 --- a/apps/web-tdesign/src/views/_core/profile/password-setting.vue +++ /dev/null @@ -1,66 +0,0 @@ - - diff --git a/apps/web-tdesign/src/views/_core/profile/security-setting.vue b/apps/web-tdesign/src/views/_core/profile/security-setting.vue deleted file mode 100644 index be30db58..00000000 --- a/apps/web-tdesign/src/views/_core/profile/security-setting.vue +++ /dev/null @@ -1,43 +0,0 @@ - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-trends.vue deleted file mode 100644 index f1f0b232..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-trends.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-data.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-data.vue deleted file mode 100644 index 190fb41f..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-data.vue +++ /dev/null @@ -1,82 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue deleted file mode 100644 index 02f50912..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue +++ /dev/null @@ -1,46 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-source.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-source.vue deleted file mode 100644 index 0915c7af..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-source.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue deleted file mode 100644 index 7e0f1013..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue +++ /dev/null @@ -1,55 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/analytics/index.vue b/apps/web-tdesign/src/views/dashboard/analytics/index.vue deleted file mode 100644 index 5e3d6d28..00000000 --- a/apps/web-tdesign/src/views/dashboard/analytics/index.vue +++ /dev/null @@ -1,90 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/dashboard/workspace/index.vue b/apps/web-tdesign/src/views/dashboard/workspace/index.vue deleted file mode 100644 index b95d6138..00000000 --- a/apps/web-tdesign/src/views/dashboard/workspace/index.vue +++ /dev/null @@ -1,266 +0,0 @@ - - - diff --git a/apps/web-tdesign/src/views/demos/tdesign/index.vue b/apps/web-tdesign/src/views/demos/tdesign/index.vue deleted file mode 100644 index f44f96e5..00000000 --- a/apps/web-tdesign/src/views/demos/tdesign/index.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - diff --git a/apps/web-tdesign/tailwind.config.mjs b/apps/web-tdesign/tailwind.config.mjs deleted file mode 100644 index f17f556f..00000000 --- a/apps/web-tdesign/tailwind.config.mjs +++ /dev/null @@ -1 +0,0 @@ -export { default } from '@vben/tailwind-config'; diff --git a/apps/web-tdesign/tsconfig.json b/apps/web-tdesign/tsconfig.json deleted file mode 100644 index 02c287fe..00000000 --- a/apps/web-tdesign/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/web-app.json", - "compilerOptions": { - "baseUrl": ".", - "paths": { - "#/*": ["./src/*"] - } - }, - "references": [{ "path": "./tsconfig.node.json" }], - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] -} diff --git a/apps/web-tdesign/tsconfig.node.json b/apps/web-tdesign/tsconfig.node.json deleted file mode 100644 index c2f0d86c..00000000 --- a/apps/web-tdesign/tsconfig.node.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "@vben/tsconfig/node.json", - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "noEmit": false - }, - "include": ["vite.config.mts"] -} diff --git a/apps/web-tdesign/vite.config.mts b/apps/web-tdesign/vite.config.mts deleted file mode 100644 index b6360f1d..00000000 --- a/apps/web-tdesign/vite.config.mts +++ /dev/null @@ -1,20 +0,0 @@ -import { defineConfig } from '@vben/vite-config'; - -export default defineConfig(async () => { - return { - application: {}, - vite: { - server: { - proxy: { - '/api': { - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ''), - // mock代理目标地址 - target: 'http://localhost:5320/api', - ws: true, - }, - }, - }, - }, - }; -}); diff --git a/package.json b/package.json index 27949a22..d8d44441 100644 --- a/package.json +++ b/package.json @@ -27,12 +27,9 @@ "scripts": { "build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build", "build:analyze": "turbo build:analyze", - "build:antd": "pnpm run build --filter=@vben/web-antd", "build:docker": "./scripts/deploy/build-local-docker-image.sh", "build:docs": "pnpm run build --filter=@vben/docs", - "build:ele": "pnpm run build --filter=@vben/web-ele", "build:naive": "pnpm run build --filter=@vben/web-naive", - "build:tdesign": "pnpm run build --filter=@vben/web-tdesign", "build:play": "pnpm run build --filter=@vben/playground", "changeset": "pnpm exec changeset", "check": "pnpm run check:circular && pnpm run check:dep && pnpm run check:type && pnpm check:cspell", @@ -43,11 +40,8 @@ "clean": "node ./scripts/clean.mjs", "commit": "czg", "dev": "turbo-run dev", - "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", - "dev:ele": "pnpm -F @vben/web-ele run dev", "dev:naive": "pnpm -F @vben/web-naive run dev", - "dev:tdesign": "pnpm -F @vben/web-tdesign run dev", "dev:play": "pnpm -F @vben/playground run dev", "format": "vsh lint --format", "lint": "vsh lint", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c817814c..005ad5af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -219,9 +219,6 @@ catalogs: echarts: specifier: ^6.0.0 version: 6.0.0 - element-plus: - specifier: ^2.10.2 - version: 2.11.7 es-toolkit: specifier: ^1.41.0 version: 1.41.0 @@ -447,9 +444,6 @@ catalogs: unbuild: specifier: ^3.6.1 version: 3.6.1 - unplugin-element-plus: - specifier: ^0.11.1 - version: 0.11.1 vee-validate: specifier: ^4.15.1 version: 4.15.1 @@ -646,136 +640,6 @@ importers: specifier: 'catalog:' version: 1.15.4 - apps/web-antd: - dependencies: - '@vben/access': - specifier: workspace:* - version: link:../../packages/effects/access - '@vben/common-ui': - specifier: workspace:* - version: link:../../packages/effects/common-ui - '@vben/constants': - specifier: workspace:* - version: link:../../packages/constants - '@vben/hooks': - specifier: workspace:* - version: link:../../packages/effects/hooks - '@vben/icons': - specifier: workspace:* - version: link:../../packages/icons - '@vben/layouts': - specifier: workspace:* - version: link:../../packages/effects/layouts - '@vben/locales': - specifier: workspace:* - version: link:../../packages/locales - '@vben/plugins': - specifier: workspace:* - version: link:../../packages/effects/plugins - '@vben/preferences': - specifier: workspace:* - version: link:../../packages/preferences - '@vben/request': - specifier: workspace:* - version: link:../../packages/effects/request - '@vben/stores': - specifier: workspace:* - version: link:../../packages/stores - '@vben/styles': - specifier: workspace:* - version: link:../../packages/styles - '@vben/types': - specifier: workspace:* - version: link:../../packages/types - '@vben/utils': - specifier: workspace:* - version: link:../../packages/utils - '@vueuse/core': - specifier: 'catalog:' - version: 13.9.0(vue@3.5.24(typescript@5.9.3)) - ant-design-vue: - specifier: 'catalog:' - version: 4.2.6(vue@3.5.24(typescript@5.9.3)) - dayjs: - specifier: 'catalog:' - version: 1.11.19 - pinia: - specifier: ^3.0.3 - version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) - vue: - specifier: ^3.5.24 - version: 3.5.24(typescript@5.9.3) - vue-router: - specifier: 'catalog:' - version: 4.6.3(vue@3.5.24(typescript@5.9.3)) - - apps/web-ele: - dependencies: - '@vben/access': - specifier: workspace:* - version: link:../../packages/effects/access - '@vben/common-ui': - specifier: workspace:* - version: link:../../packages/effects/common-ui - '@vben/constants': - specifier: workspace:* - version: link:../../packages/constants - '@vben/hooks': - specifier: workspace:* - version: link:../../packages/effects/hooks - '@vben/icons': - specifier: workspace:* - version: link:../../packages/icons - '@vben/layouts': - specifier: workspace:* - version: link:../../packages/effects/layouts - '@vben/locales': - specifier: workspace:* - version: link:../../packages/locales - '@vben/plugins': - specifier: workspace:* - version: link:../../packages/effects/plugins - '@vben/preferences': - specifier: workspace:* - version: link:../../packages/preferences - '@vben/request': - specifier: workspace:* - version: link:../../packages/effects/request - '@vben/stores': - specifier: workspace:* - version: link:../../packages/stores - '@vben/styles': - specifier: workspace:* - version: link:../../packages/styles - '@vben/types': - specifier: workspace:* - version: link:../../packages/types - '@vben/utils': - specifier: workspace:* - version: link:../../packages/utils - '@vueuse/core': - specifier: 'catalog:' - version: 13.9.0(vue@3.5.24(typescript@5.9.3)) - dayjs: - specifier: 'catalog:' - version: 1.11.19 - element-plus: - specifier: 'catalog:' - version: 2.11.7(vue@3.5.24(typescript@5.9.3)) - pinia: - specifier: ^3.0.3 - version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) - vue: - specifier: ^3.5.24 - version: 3.5.24(typescript@5.9.3) - vue-router: - specifier: 'catalog:' - version: 4.6.3(vue@3.5.24(typescript@5.9.3)) - devDependencies: - unplugin-element-plus: - specifier: 'catalog:' - version: 0.11.1 - apps/web-naive: dependencies: '@vben/access': @@ -836,76 +700,6 @@ importers: specifier: 'catalog:' version: 4.6.3(vue@3.5.24(typescript@5.9.3)) - apps/web-tdesign: - dependencies: - '@vben/access': - specifier: workspace:* - version: link:../../packages/effects/access - '@vben/common-ui': - specifier: workspace:* - version: link:../../packages/effects/common-ui - '@vben/constants': - specifier: workspace:* - version: link:../../packages/constants - '@vben/hooks': - specifier: workspace:* - version: link:../../packages/effects/hooks - '@vben/icons': - specifier: workspace:* - version: link:../../packages/icons - '@vben/layouts': - specifier: workspace:* - version: link:../../packages/effects/layouts - '@vben/locales': - specifier: workspace:* - version: link:../../packages/locales - '@vben/plugins': - specifier: workspace:* - version: link:../../packages/effects/plugins - '@vben/preferences': - specifier: workspace:* - version: link:../../packages/preferences - '@vben/request': - specifier: workspace:* - version: link:../../packages/effects/request - '@vben/stores': - specifier: workspace:* - version: link:../../packages/stores - '@vben/styles': - specifier: workspace:* - version: link:../../packages/styles - '@vben/types': - specifier: workspace:* - version: link:../../packages/types - '@vben/utils': - specifier: workspace:* - version: link:../../packages/utils - '@vueuse/core': - specifier: 'catalog:' - version: 13.9.0(vue@3.5.24(typescript@5.9.3)) - dayjs: - specifier: 'catalog:' - version: 1.11.19 - es-toolkit: - specifier: 'catalog:' - version: 1.41.0 - pinia: - specifier: ^3.0.3 - version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) - tdesign-vue-next: - specifier: ^1.17.1 - version: 1.17.2(vue@3.5.24(typescript@5.9.3)) - vue: - specifier: ^3.5.24 - version: 3.5.24(typescript@5.9.3) - vue-router: - specifier: 'catalog:' - version: 4.6.3(vue@3.5.24(typescript@5.9.3)) - devDependencies: - '@types/lodash-es': - specifier: ^4.17.12 - version: 4.17.12 - docs: dependencies: '@vben-core/shadcn-ui': @@ -3389,11 +3183,6 @@ packages: '@dual-bundle/import-meta-resolve@4.2.1': resolution: {integrity: sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==} - '@element-plus/icons-vue@2.3.2': - resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==} - peerDependencies: - vue: ^3.5.24 - '@emnapi/core@1.7.0': resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} @@ -4472,9 +4261,6 @@ packages: '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@sxzz/popperjs-es@2.11.7': - resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} - '@tailwindcss/nesting@0.0.0-insiders.565cd3e': resolution: {integrity: sha512-WhHoFBx19TnH/c+xLwT/sxei6+4RpdfiyG3MYXfmLaMsADmVqBkF7B6lDalgZD9YdM459MF7DtxVbWkOrV7IaQ==} peerDependencies: @@ -4638,21 +4424,12 @@ packages: '@types/sortablejs@1.15.9': resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==} - '@types/tinycolor2@1.4.6': - resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} - '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/validator@13.15.4': - resolution: {integrity: sha512-LSFfpSnJJY9wbC0LQxgvfb+ynbHftFo0tMsFOl/J4wexLnYMmDSPaj2ZyDv3TkfL1UePxPrxOWJfbiRS8mQv7A==} - - '@types/web-bluetooth@0.0.16': - resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} - '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} @@ -5075,9 +4852,6 @@ packages: peerDependencies: vue: ^3.5.24 - '@vueuse/core@9.13.0': - resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} - '@vueuse/integrations@12.8.2': resolution: {integrity: sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==} peerDependencies: @@ -5170,9 +4944,6 @@ packages: '@vueuse/metadata@14.0.0': resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==} - '@vueuse/metadata@9.13.0': - resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} - '@vueuse/motion@3.0.3': resolution: {integrity: sha512-4B+ITsxCI9cojikvrpaJcLXyq0spj3sdlzXjzesWdMRd99hhtFI6OJ/1JsqwtF73YooLe0hUn/xDR6qCtmn5GQ==} peerDependencies: @@ -5191,9 +4962,6 @@ packages: peerDependencies: vue: ^3.5.24 - '@vueuse/shared@9.13.0': - resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} - '@vxe-ui/core@4.2.14': resolution: {integrity: sha512-ONu8vgW8+q0SFtAoUEPZibFjlx0nzAKTqTXD9pO2AmgYCIMtYIePFLnqiHIYaYfH/dCibVZ6KGWUc/wqxnbGDw==} peerDependencies: @@ -6343,11 +6111,6 @@ packages: electron-to-chromium@1.5.250: resolution: {integrity: sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw==} - element-plus@2.11.7: - resolution: {integrity: sha512-Bh47wuzsqaNBNDkbtlOlZER1cGcOB8GsXp/+C9b95MOrk0wvoHUV4NKKK7xMkfYNFYdYysQ752oMhnExgAL6+g==} - peerDependencies: - vue: ^3.5.24 - emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} @@ -7820,13 +7583,6 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - lodash-unified@1.0.3: - resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} - peerDependencies: - '@types/lodash-es': '*' - lodash: '*' - lodash-es: '*' - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -7975,9 +7731,6 @@ packages: medium-zoom@1.1.0: resolution: {integrity: sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==} - memoize-one@6.0.0: - resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} - meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} engines: {node: '>=16.10'} @@ -8270,9 +8023,6 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} - normalize-wheel-es@1.2.0: - resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} - npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -9971,17 +9721,6 @@ packages: resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} engines: {node: '>=18'} - tdesign-icons-vue-next@0.4.1: - resolution: {integrity: sha512-uDPuTLRORnGcTyVGNoentNaK4V+ZcBmhYwcY3KqDaQQ5rrPeLMxu0ZVmgOEf0JtF2QZiqAxY7vodNEiLUdoRKA==} - peerDependencies: - vue: ^3.5.24 - - tdesign-vue-next@1.17.2: - resolution: {integrity: sha512-nTofPSKGQguOS+Lb62fDiLS1Rs3Ngzb8rE8sPEjfMdDjdFZ5kEUgvVp+J+8GKfgwVRAZRjv//qSzZVt6cqgXxA==} - engines: {node: '>= 18'} - peerDependencies: - vue: ^3.5.24 - temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -10029,9 +9768,6 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinycolor2@1.6.0: - resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} - tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -10288,10 +10024,6 @@ packages: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - unplugin-element-plus@0.11.1: - resolution: {integrity: sha512-pj6+SCBWfHrCrkaXDcDwHvT6u2XURFOwDFd8V5Nweq4xtr/91sAg/xNoih96FK3y89nqnHQ6qINilSGH2sUtmg==} - engines: {node: '>=20.19.0'} - unplugin-utils@0.3.1: resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} engines: {node: '>=20.19.0'} @@ -10403,10 +10135,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - validator@13.15.20: - resolution: {integrity: sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==} - engines: {node: '>= 0.10'} - vdirs@0.1.8: resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} peerDependencies: @@ -12684,10 +12412,6 @@ snapshots: '@dual-bundle/import-meta-resolve@4.2.1': {} - '@element-plus/icons-vue@2.3.2(vue@3.5.24(typescript@5.9.3))': - dependencies: - vue: 3.5.24(typescript@5.9.3) - '@emnapi/core@1.7.0': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -13254,6 +12978,7 @@ snapshots: untyped: 2.0.0 transitivePeerDependencies: - magicast + optional: true '@one-ini/wasm@0.1.1': {} @@ -13792,8 +13517,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@sxzz/popperjs-es@2.11.7': {} - '@tailwindcss/nesting@0.0.0-insiders.565cd3e(postcss@8.5.6)': dependencies: postcss: 8.5.6 @@ -13954,16 +13677,10 @@ snapshots: '@types/sortablejs@1.15.9': {} - '@types/tinycolor2@1.4.6': {} - '@types/trusted-types@2.0.7': {} '@types/unist@3.0.3': {} - '@types/validator@13.15.4': {} - - '@types/web-bluetooth@0.0.16': {} - '@types/web-bluetooth@0.0.21': {} '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': @@ -14524,16 +14241,6 @@ snapshots: '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3)) vue: 3.5.24(typescript@5.9.3) - '@vueuse/core@9.13.0(vue@3.5.24(typescript@5.9.3))': - dependencies: - '@types/web-bluetooth': 0.0.16 - '@vueuse/metadata': 9.13.0 - '@vueuse/shared': 9.13.0(vue@3.5.24(typescript@5.9.3)) - vue-demi: 0.14.10(vue@3.5.24(typescript@5.9.3)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - '@vueuse/integrations@12.8.2(async-validator@4.2.5)(axios@1.13.2)(focus-trap@7.6.6)(nprogress@0.2.0)(qrcode@1.5.4)(sortablejs@1.15.6)(typescript@5.9.3)': dependencies: '@vueuse/core': 12.8.2(typescript@5.9.3) @@ -14568,8 +14275,6 @@ snapshots: '@vueuse/metadata@14.0.0': {} - '@vueuse/metadata@9.13.0': {} - '@vueuse/motion@3.0.3(vue@3.5.24(typescript@5.9.3))': dependencies: '@vueuse/core': 13.9.0(vue@3.5.24(typescript@5.9.3)) @@ -14598,13 +14303,6 @@ snapshots: dependencies: vue: 3.5.24(typescript@5.9.3) - '@vueuse/shared@9.13.0(vue@3.5.24(typescript@5.9.3))': - dependencies: - vue-demi: 0.14.10(vue@3.5.24(typescript@5.9.3)) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - '@vxe-ui/core@4.2.14(vue@3.5.24(typescript@5.9.3))': dependencies: dom-zindex: 1.0.6 @@ -15840,26 +15538,6 @@ snapshots: electron-to-chromium@1.5.250: {} - element-plus@2.11.7(vue@3.5.24(typescript@5.9.3)): - dependencies: - '@ctrl/tinycolor': 4.2.0 - '@element-plus/icons-vue': 2.3.2(vue@3.5.24(typescript@5.9.3)) - '@floating-ui/dom': 1.7.4 - '@popperjs/core': '@sxzz/popperjs-es@2.11.7' - '@types/lodash': 4.17.20 - '@types/lodash-es': 4.17.12 - '@vueuse/core': 9.13.0(vue@3.5.24(typescript@5.9.3)) - async-validator: 4.2.5 - dayjs: 1.11.19 - lodash: 4.17.21 - lodash-es: 4.17.21 - lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21) - memoize-one: 6.0.0 - normalize-wheel-es: 1.2.0 - vue: 3.5.24(typescript@5.9.3) - transitivePeerDependencies: - - '@vue/composition-api' - emoji-regex-xs@1.0.0: {} emoji-regex@10.6.0: {} @@ -15910,7 +15588,8 @@ snapshots: error-stack-parser-es@1.0.5: {} - errx@0.1.0: {} + errx@0.1.0: + optional: true es-abstract@1.24.0: dependencies: @@ -17471,12 +17150,6 @@ snapshots: lodash-es@4.17.21: {} - lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21): - dependencies: - '@types/lodash-es': 4.17.12 - lodash: 4.17.21 - lodash-es: 4.17.21 - lodash.camelcase@4.3.0: {} lodash.clonedeep@4.5.0: {} @@ -17610,8 +17283,6 @@ snapshots: medium-zoom@1.1.0: {} - memoize-one@6.0.0: {} - meow@12.1.1: {} meow@13.2.0: {} @@ -17969,8 +17640,6 @@ snapshots: normalize-range@0.1.2: {} - normalize-wheel-es@1.2.0: {} - npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -19789,28 +19458,6 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - tdesign-icons-vue-next@0.4.1(vue@3.5.24(typescript@5.9.3)): - dependencies: - '@babel/runtime': 7.28.4 - vue: 3.5.24(typescript@5.9.3) - - tdesign-vue-next@1.17.2(vue@3.5.24(typescript@5.9.3)): - dependencies: - '@babel/runtime': 7.28.4 - '@popperjs/core': 2.11.8 - '@types/lodash-es': 4.17.12 - '@types/sortablejs': 1.15.9 - '@types/tinycolor2': 1.4.6 - '@types/validator': 13.15.4 - dayjs: 1.11.19 - lodash-es: 4.17.21 - mitt: 3.0.1 - sortablejs: 1.15.6 - tdesign-icons-vue-next: 0.4.1(vue@3.5.24(typescript@5.9.3)) - tinycolor2: 1.6.0 - validator: 13.15.20 - vue: 3.5.24(typescript@5.9.3) - temp-dir@2.0.0: {} tempy@0.6.0: @@ -19855,8 +19502,6 @@ snapshots: tinybench@2.9.0: {} - tinycolor2@1.6.0: {} - tinyexec@0.3.2: {} tinyexec@1.0.2: {} @@ -20126,16 +19771,6 @@ snapshots: universalify@2.0.1: {} - unplugin-element-plus@0.11.1: - dependencies: - '@nuxt/kit': 4.2.1 - es-module-lexer: 1.7.0 - escape-string-regexp: 5.0.0 - magic-string: 0.30.21 - unplugin: 2.3.10 - transitivePeerDependencies: - - magicast - unplugin-utils@0.3.1: dependencies: pathe: 2.0.3 @@ -20249,8 +19884,6 @@ snapshots: util-deprecate@1.0.2: {} - validator@13.15.20: {} - vdirs@0.1.8(vue@3.5.24(typescript@5.9.3)): dependencies: evtd: 0.2.4 diff --git a/vben-admin.code-workspace b/vben-admin.code-workspace index 33df5a75..ff084b71 100644 --- a/vben-admin.code-workspace +++ b/vben-admin.code-workspace @@ -4,22 +4,10 @@ "name": "@vben/backend-mock", "path": "apps/backend-mock", }, - { - "name": "@vben/web-antd", - "path": "apps/web-antd", - }, - { - "name": "@vben/web-ele", - "path": "apps/web-ele", - }, { "name": "@vben/web-naive", "path": "apps/web-naive", }, - { - "name": "@vben/web-tdesign", - "path": "apps/web-tdesign", - }, { "name": "@vben/docs", "path": "docs",