├── .changeset
├── README.md
└── config.json
├── .commitlintrc.js
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── 1-bug.md
│ ├── 2-feature.md
│ ├── 3-bug-cn.md
│ └── config.yml
├── commit-convention.md
├── contributing.md
├── pull_request_template.md
└── workflows
│ ├── deploy.yml
│ ├── ftp-schedule.yml
│ ├── issue-close-require.yml
│ ├── issue-labeled.yml
│ └── release.yml
├── .gitignore
├── .gitpod.yml
├── .lintstagedrc.js
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .stylelintignore
├── .stylelintrc.js
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── LICENSE
├── README.md
├── README.zh-CN.md
├── apps
├── amis
│ ├── .env.development
│ ├── .gitignore
│ ├── .prettierrc
│ ├── App.tsx
│ ├── Dockerfile
│ ├── README.md
│ ├── auth
│ │ ├── login.html
│ │ ├── login.tsx
│ │ ├── logincallback.html
│ │ └── logincallback.tsx
│ ├── component
│ │ ├── AMISRenderer.tsx
│ │ └── AddPageModal.tsx
│ ├── deploy-gh-pages.sh
│ ├── editor.html
│ ├── editor
│ │ └── MyRenderer.tsx
│ ├── fis-conf.js
│ ├── index.html
│ ├── index.tsx
│ ├── loadMonacoEditor.ts
│ ├── mod.js
│ ├── package.json
│ ├── renderer
│ │ └── MyRenderer.tsx
│ ├── route
│ │ ├── Editor copy.tsx
│ │ ├── Editor.tsx
│ │ ├── EditorUmi.tsx
│ │ ├── NotFound.tsx
│ │ ├── Preview.tsx
│ │ ├── View.tsx
│ │ ├── auth
│ │ │ └── authService.ts
│ │ ├── index.tsx
│ │ └── oldEditor.tsx
│ ├── scss
│ │ └── style.scss
│ ├── service
│ │ └── api.ts
│ ├── store
│ │ ├── Page.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── upload2cdn.js
│ └── yarn.lock
└── ant-admin
│ ├── .env
│ ├── .env.development
│ ├── .env.production
│ ├── .env.staging
│ ├── .env.test
│ ├── index.html
│ ├── mock
│ ├── _mock-server.ts
│ ├── _util.ts
│ ├── demo
│ │ ├── account.ts
│ │ ├── api-cascader.ts
│ │ ├── select-demo.ts
│ │ ├── system.ts
│ │ ├── table-demo.ts
│ │ └── tree-demo.ts
│ └── sys
│ │ ├── menu.ts
│ │ └── user.ts
│ ├── package.json
│ ├── postcss.config.js
│ ├── public
│ ├── favicon.ico
│ ├── img
│ │ └── logo.png
│ └── resource
│ │ ├── img
│ │ ├── logo.png
│ │ ├── pwa-192x192.png
│ │ └── pwa-512x512.png
│ │ └── tinymce
│ │ ├── langs
│ │ ├── en.js
│ │ └── zh_CN.js
│ │ └── skins
│ │ └── ui
│ │ ├── oxide-dark
│ │ ├── content.inline.min.css
│ │ ├── content.min.css
│ │ ├── content.mobile.min.css
│ │ ├── skin.min.css
│ │ └── skin.mobile.min.css
│ │ └── oxide
│ │ ├── content.inline.min.css
│ │ ├── content.min.css
│ │ ├── content.mobile.min.css
│ │ ├── fonts
│ │ └── tinymce-mobile.woff
│ │ ├── skin.min.css
│ │ └── skin.mobile.min.css
│ ├── scripts
│ ├── build-config.ts
│ ├── generate-icon.ts
│ └── post-build.ts
│ ├── src
│ ├── api
│ │ ├── ContentTypeService.ts
│ │ ├── VbenFormService.ts
│ │ ├── VbenListService.ts
│ │ ├── authService.ts
│ │ ├── contentHelper.ts
│ │ └── ocUtils.ts
│ ├── app.vue
│ ├── assets
│ │ ├── icons
│ │ │ ├── download-count.svg
│ │ │ ├── dynamic-avatar-1.svg
│ │ │ ├── dynamic-avatar-2.svg
│ │ │ ├── dynamic-avatar-3.svg
│ │ │ ├── dynamic-avatar-4.svg
│ │ │ ├── dynamic-avatar-5.svg
│ │ │ ├── dynamic-avatar-6.svg
│ │ │ ├── moon.svg
│ │ │ ├── sun.svg
│ │ │ ├── test.svg
│ │ │ ├── total-sales.svg
│ │ │ ├── transaction.svg
│ │ │ └── visit-count.svg
│ │ ├── images
│ │ │ ├── demo.png
│ │ │ ├── header.jpg
│ │ │ └── logo.png
│ │ └── svg
│ │ │ ├── illustration.svg
│ │ │ ├── login-bg-dark.svg
│ │ │ ├── login-bg.svg
│ │ │ ├── login-box-bg.svg
│ │ │ ├── net-error.svg
│ │ │ └── no-data.svg
│ ├── components
│ │ ├── Amis
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── amisEnv.ts
│ │ │ │ ├── index.vue
│ │ │ │ ├── react_app
│ │ │ │ ├── MyRenderer.tsx
│ │ │ │ └── Renderer.jsx
│ │ │ │ ├── style
│ │ │ │ └── themes
│ │ │ │ │ ├── ang.less
│ │ │ │ │ ├── antd.less
│ │ │ │ │ ├── antd_var.less
│ │ │ │ │ ├── cxd.less
│ │ │ │ │ ├── cxd
│ │ │ │ │ ├── fix.less
│ │ │ │ │ └── fixvars.less
│ │ │ │ │ ├── dark.less
│ │ │ │ │ └── default.less
│ │ │ │ ├── types
│ │ │ │ └── index.ts
│ │ │ │ ├── veauryAMISRenderer.vue
│ │ │ │ └── vue
│ │ │ │ ├── AA.vue
│ │ │ │ └── Basic.vue
│ │ ├── Authority
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ └── index.vue
│ │ ├── CodeEditor
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── CodeEditor.vue
│ │ │ │ ├── codemirror
│ │ │ │ ├── CodeMirror.vue
│ │ │ │ ├── codeMirror.ts
│ │ │ │ └── codemirror.css
│ │ │ │ ├── json-preview
│ │ │ │ └── JsonPreview.vue
│ │ │ │ └── typing.ts
│ │ ├── MonacoEditor
│ │ │ └── index.vue
│ │ ├── OrchardCore
│ │ │ ├── hooks
│ │ │ │ └── useContentForm.ts
│ │ │ ├── index.ts
│ │ │ ├── src
│ │ │ │ ├── ContentForm.vue
│ │ │ │ └── props.ts
│ │ │ └── types
│ │ │ │ └── ContentFormProps.ts
│ │ ├── Tree
│ │ │ ├── index.ts
│ │ │ ├── src
│ │ │ │ ├── index.vue
│ │ │ │ ├── tree-header.vue
│ │ │ │ ├── tree-icon.ts
│ │ │ │ ├── tree.ts
│ │ │ │ └── use-tree.ts
│ │ │ └── style
│ │ │ │ ├── index.less
│ │ │ │ └── index.ts
│ │ ├── Upload
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── data.tsx
│ │ │ │ ├── file-list.vue
│ │ │ │ ├── helper.ts
│ │ │ │ ├── index.vue
│ │ │ │ ├── props.ts
│ │ │ │ ├── thumb-url.vue
│ │ │ │ ├── typing.ts
│ │ │ │ ├── upload-modal.vue
│ │ │ │ ├── upload-preview-modal.vue
│ │ │ │ └── use-upload.ts
│ │ ├── application
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── AppDarkModeToggle.vue
│ │ │ │ ├── AppLocalePicker.vue
│ │ │ │ ├── AppLogo.vue
│ │ │ │ ├── AppProvider.vue
│ │ │ │ ├── search
│ │ │ │ ├── AppSearch.vue
│ │ │ │ ├── AppSearchFooter.vue
│ │ │ │ ├── AppSearchKeyItem.vue
│ │ │ │ ├── AppSearchModal.vue
│ │ │ │ └── useMenuSearch.ts
│ │ │ │ └── useAppContext.ts
│ │ ├── basic
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── BasicArrow.vue
│ │ │ │ ├── BasicHelp.vue
│ │ │ │ └── BasicTitle.vue
│ │ ├── button
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ └── PopConfirmButton.vue
│ │ ├── card-list
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── CardList.vue
│ │ │ │ └── data.ts
│ │ ├── container
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── ScrollContainer.vue
│ │ │ │ ├── collapse
│ │ │ │ ├── CollapseContainer.vue
│ │ │ │ └── CollapseHeader.vue
│ │ │ │ └── typing.ts
│ │ ├── context-menu
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── ContextMenu.vue
│ │ │ │ ├── createContextMenu.ts
│ │ │ │ └── typing.ts
│ │ ├── count-down
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── CountButton.vue
│ │ │ │ ├── CountdownInput.vue
│ │ │ │ └── useCountdown.ts
│ │ ├── cropper
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── CopperModal.vue
│ │ │ │ ├── Cropper.vue
│ │ │ │ ├── CropperAvatar.vue
│ │ │ │ └── typing.ts
│ │ ├── description
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── Description.vue
│ │ │ │ ├── typing.ts
│ │ │ │ └── useDescription.ts
│ │ ├── drawer
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── BasicDrawer.vue
│ │ │ │ ├── components
│ │ │ │ ├── DrawerFooter.vue
│ │ │ │ └── DrawerHeader.vue
│ │ │ │ ├── props.ts
│ │ │ │ ├── typing.ts
│ │ │ │ └── useDrawer.ts
│ │ ├── dropdown
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── Dropdown.vue
│ │ │ │ └── typing.ts
│ │ ├── form
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── BasicForm.vue
│ │ │ │ ├── componentMap.ts
│ │ │ │ ├── components
│ │ │ │ ├── ApiCascader.vue
│ │ │ │ ├── ApiRadioGroup.vue
│ │ │ │ ├── ApiSelect.vue
│ │ │ │ ├── ApiTreeSelect.vue
│ │ │ │ ├── ContentTreeSelect.vue
│ │ │ │ ├── FormAction.vue
│ │ │ │ ├── FormItem.vue
│ │ │ │ └── RadioButtonGroup.vue
│ │ │ │ ├── helper.ts
│ │ │ │ ├── hooks
│ │ │ │ ├── useAdvanced.ts
│ │ │ │ ├── useAutoFocus.ts
│ │ │ │ ├── useComponentRegister.ts
│ │ │ │ ├── useForm.ts
│ │ │ │ ├── useFormContext.ts
│ │ │ │ ├── useFormEvents.ts
│ │ │ │ ├── useFormValues.ts
│ │ │ │ └── useLabelWidth.ts
│ │ │ │ ├── props.ts
│ │ │ │ └── types
│ │ │ │ ├── form.ts
│ │ │ │ ├── formItem.ts
│ │ │ │ ├── hooks.ts
│ │ │ │ └── index.ts
│ │ ├── icon
│ │ │ ├── data
│ │ │ │ └── icons.data.ts
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ └── IconPicker.vue
│ │ ├── loading
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── Loading.vue
│ │ │ │ ├── createLoading.ts
│ │ │ │ ├── typing.ts
│ │ │ │ └── useLoading.ts
│ │ ├── menu
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── BasicMenu.vue
│ │ │ │ ├── components
│ │ │ │ ├── BasicMenuItem.vue
│ │ │ │ ├── BasicSubMenuItem.vue
│ │ │ │ └── MenuItemContent.vue
│ │ │ │ ├── index.less
│ │ │ │ ├── props.ts
│ │ │ │ ├── types.ts
│ │ │ │ └── useOpenKeys.ts
│ │ ├── modal
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── BasicModal.vue
│ │ │ │ ├── components
│ │ │ │ ├── Modal.tsx
│ │ │ │ ├── ModalClose.vue
│ │ │ │ ├── ModalFooter.vue
│ │ │ │ ├── ModalHeader.vue
│ │ │ │ └── ModalWrapper.vue
│ │ │ │ ├── hooks
│ │ │ │ ├── useModal.ts
│ │ │ │ ├── useModalContext.ts
│ │ │ │ ├── useModalDrag.ts
│ │ │ │ └── useModalFullScreen.ts
│ │ │ │ ├── index.less
│ │ │ │ ├── props.ts
│ │ │ │ └── typing.ts
│ │ ├── page
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── PageFooter.vue
│ │ │ │ ├── PageWrapper.vue
│ │ │ │ └── useContentHeight.ts
│ │ ├── scrollbar
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── Scrollbar.vue
│ │ │ │ ├── bar.ts
│ │ │ │ ├── types.d.ts
│ │ │ │ └── util.ts
│ │ ├── simple-menu
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ │ ├── SimpleMenu.vue
│ │ │ │ ├── SimpleMenuTag.vue
│ │ │ │ ├── SimpleSubMenu.vue
│ │ │ │ ├── components
│ │ │ │ ├── Menu.vue
│ │ │ │ ├── MenuCollapseTransition.vue
│ │ │ │ ├── MenuItem.vue
│ │ │ │ ├── SubMenuItem.vue
│ │ │ │ ├── menu.less
│ │ │ │ ├── types.ts
│ │ │ │ ├── useMenu.ts
│ │ │ │ └── useSimpleMenuContext.ts
│ │ │ │ ├── index.less
│ │ │ │ ├── types.ts
│ │ │ │ └── useOpenKeys.ts
│ │ └── table
│ │ │ ├── index.ts
│ │ │ └── src
│ │ │ ├── BasicTable.vue
│ │ │ ├── componentMap.ts
│ │ │ ├── components
│ │ │ ├── EditTableHeaderIcon.vue
│ │ │ ├── HeaderCell.vue
│ │ │ ├── TableAction.vue
│ │ │ ├── TableFooter.vue
│ │ │ ├── TableHeader.vue
│ │ │ ├── TableImg.vue
│ │ │ ├── TableTitle.vue
│ │ │ ├── editable
│ │ │ │ ├── CellComponent.ts
│ │ │ │ ├── EditableCell.vue
│ │ │ │ ├── helper.ts
│ │ │ │ └── index.ts
│ │ │ └── settings
│ │ │ │ ├── ColumnSetting.vue
│ │ │ │ ├── FullScreenSetting.vue
│ │ │ │ ├── RedoSetting.vue
│ │ │ │ ├── SizeSetting.vue
│ │ │ │ └── index.vue
│ │ │ ├── const.ts
│ │ │ ├── hooks
│ │ │ ├── useColumns.ts
│ │ │ ├── useCustomRow.ts
│ │ │ ├── useDataSource.ts
│ │ │ ├── useLoading.ts
│ │ │ ├── usePagination.tsx
│ │ │ ├── useRowSelection.ts
│ │ │ ├── useScrollTo.ts
│ │ │ ├── useTable.ts
│ │ │ ├── useTableContext.ts
│ │ │ ├── useTableExpand.ts
│ │ │ ├── useTableFooter.ts
│ │ │ ├── useTableForm.ts
│ │ │ ├── useTableHeader.ts
│ │ │ ├── useTableScroll.ts
│ │ │ └── useTableStyle.ts
│ │ │ ├── props.ts
│ │ │ └── types
│ │ │ ├── column.ts
│ │ │ ├── componentType.ts
│ │ │ ├── pagination.ts
│ │ │ ├── table.ts
│ │ │ └── tableAction.ts
│ ├── global-components.d.ts
│ ├── hooks
│ │ ├── component
│ │ │ ├── use-form-item.ts
│ │ │ └── use-page-context.ts
│ │ ├── event
│ │ │ ├── use-breakpoint.ts
│ │ │ ├── use-event-listener.ts
│ │ │ └── use-scroll-to.ts
│ │ ├── setting
│ │ │ ├── useHeaderSetting.ts
│ │ │ ├── useMenuSetting.ts
│ │ │ ├── useMultipleTabSetting.ts
│ │ │ └── useRootSetting.ts
│ │ └── web
│ │ │ ├── use-app-inject.ts
│ │ │ ├── use-echarts
│ │ │ ├── echarts.ts
│ │ │ └── index.ts
│ │ │ ├── use-tabs.ts
│ │ │ ├── useContextMenu.ts
│ │ │ ├── useCopyToClipboard.ts
│ │ │ ├── useDesign.ts
│ │ │ ├── useFullContent.ts
│ │ │ ├── useLockPage.ts
│ │ │ ├── useMessage.tsx
│ │ │ ├── usePage.ts
│ │ │ ├── usePermission.ts
│ │ │ └── useSortable.ts
│ ├── init-packages.ts
│ ├── internal
│ │ ├── component.ts
│ │ ├── config.ts
│ │ ├── factory
│ │ │ ├── component-factory.ts
│ │ │ └── index.ts
│ │ ├── index.ts
│ │ └── pinia
│ │ │ ├── index.ts
│ │ │ └── persist.ts
│ ├── layouts
│ │ ├── default
│ │ │ ├── content
│ │ │ │ ├── index.vue
│ │ │ │ ├── useContentContext.ts
│ │ │ │ └── useContentViewHeight.ts
│ │ │ ├── feature
│ │ │ │ └── index.vue
│ │ │ ├── footer
│ │ │ │ └── index.vue
│ │ │ ├── header
│ │ │ │ ├── MultipleHeader.vue
│ │ │ │ ├── components
│ │ │ │ │ ├── Breadcrumb.vue
│ │ │ │ │ ├── ErrorAction.vue
│ │ │ │ │ ├── FullScreen.vue
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── lock
│ │ │ │ │ │ └── LockModal.vue
│ │ │ │ │ ├── notify
│ │ │ │ │ │ ├── NoticeList.vue
│ │ │ │ │ │ ├── data.ts
│ │ │ │ │ │ └── index.vue
│ │ │ │ │ └── user-dropdown
│ │ │ │ │ │ ├── DropMenuItem.vue
│ │ │ │ │ │ └── index.vue
│ │ │ │ ├── index.less
│ │ │ │ └── index.vue
│ │ │ ├── index.vue
│ │ │ ├── menu
│ │ │ │ ├── index.vue
│ │ │ │ └── useLayoutMenu.ts
│ │ │ ├── setting
│ │ │ │ ├── SettingDrawer.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── InputNumberItem.vue
│ │ │ │ │ ├── SelectItem.vue
│ │ │ │ │ ├── SettingFooter.vue
│ │ │ │ │ ├── SwitchItem.vue
│ │ │ │ │ ├── ThemeColorPicker.vue
│ │ │ │ │ ├── TypePicker.vue
│ │ │ │ │ └── index.ts
│ │ │ │ ├── enum.ts
│ │ │ │ ├── handler.ts
│ │ │ │ └── index.vue
│ │ │ ├── sider
│ │ │ │ ├── DragBar.vue
│ │ │ │ ├── LayoutSider.vue
│ │ │ │ ├── MixSider.vue
│ │ │ │ ├── index.vue
│ │ │ │ └── useLayoutSider.ts
│ │ │ ├── tabs
│ │ │ │ ├── components
│ │ │ │ │ ├── FoldButton.vue
│ │ │ │ │ ├── TabContent.vue
│ │ │ │ │ └── TabRedo.vue
│ │ │ │ ├── index.less
│ │ │ │ ├── index.vue
│ │ │ │ ├── types.ts
│ │ │ │ ├── useMultipleTabs.ts
│ │ │ │ └── useTabDropdown.ts
│ │ │ └── trigger
│ │ │ │ ├── HeaderTrigger.vue
│ │ │ │ ├── SiderTrigger.vue
│ │ │ │ └── index.vue
│ │ ├── iframe
│ │ │ ├── index.vue
│ │ │ └── use-frame-keepalive.ts
│ │ └── page
│ │ │ └── index.vue
│ ├── logics
│ │ ├── init-app-config.ts
│ │ ├── mitt
│ │ │ └── route-change.ts
│ │ └── theme
│ │ │ ├── dark.ts
│ │ │ ├── index.ts
│ │ │ ├── theme.ts
│ │ │ ├── update-background.ts
│ │ │ ├── update-color-weak.ts
│ │ │ ├── update-gray-mode.ts
│ │ │ └── util.ts
│ ├── main.ts
│ ├── router
│ │ ├── constant.ts
│ │ ├── guard
│ │ │ ├── index.ts
│ │ │ ├── param-menu.ts
│ │ │ ├── permission.ts
│ │ │ └── state.ts
│ │ ├── helper
│ │ │ ├── menu.ts
│ │ │ └── route.ts
│ │ ├── index.ts
│ │ ├── menus
│ │ │ └── index.ts
│ │ ├── routes
│ │ │ ├── backend
│ │ │ │ └── static-menus.ts
│ │ │ ├── basic.ts
│ │ │ ├── index.ts
│ │ │ ├── mainOut.ts
│ │ │ └── modules
│ │ │ │ ├── about.ts
│ │ │ │ ├── amis.ts
│ │ │ │ ├── crm
│ │ │ │ └── index.ts
│ │ │ │ ├── dashboard.ts
│ │ │ │ ├── develop.ts
│ │ │ │ └── system.ts
│ │ └── types.ts
│ ├── store
│ │ ├── app.ts
│ │ ├── error-log.ts
│ │ ├── lock.ts
│ │ ├── multiple-tab.ts
│ │ ├── permission.ts
│ │ └── user.ts
│ ├── styles
│ │ ├── ant
│ │ │ ├── amis_override.less
│ │ │ ├── index.less
│ │ │ ├── pagination.less
│ │ │ └── table.less
│ │ ├── color.less
│ │ ├── config.less
│ │ ├── index.less
│ │ ├── index.ts
│ │ ├── public.less
│ │ ├── tailwind.css
│ │ ├── theme.less
│ │ ├── transition.less
│ │ └── var
│ │ │ ├── breakpoint.less
│ │ │ ├── easing.less
│ │ │ └── index.less
│ └── views
│ │ ├── CRM
│ │ └── Customer
│ │ │ ├── EditModal.vue
│ │ │ ├── data.ts
│ │ │ └── index.vue
│ │ ├── DynamicPage
│ │ ├── EditContentTypeDrawer.vue
│ │ ├── EditModal.vue
│ │ └── index.vue
│ │ ├── amis
│ │ ├── AmisDynamic.vue
│ │ ├── Editor.vue
│ │ ├── GenCrud.ts
│ │ ├── GenFromType.json
│ │ ├── GenFromType.vue
│ │ ├── index.json
│ │ ├── index.vue
│ │ └── schematpls
│ │ │ ├── crud.json
│ │ │ └── formItem_contentPicker.json
│ │ ├── dashboard
│ │ ├── analysis
│ │ │ ├── components
│ │ │ │ ├── GrowCard.vue
│ │ │ │ ├── SalesProductPie.vue
│ │ │ │ ├── SiteAnalysis.vue
│ │ │ │ ├── VisitAnalysis.vue
│ │ │ │ ├── VisitAnalysisBar.vue
│ │ │ │ ├── VisitRadar.vue
│ │ │ │ ├── VisitSource.vue
│ │ │ │ └── props.ts
│ │ │ ├── data.ts
│ │ │ └── index.vue
│ │ └── workbench
│ │ │ ├── components
│ │ │ ├── DynamicInfo.vue
│ │ │ ├── ProjectCard.vue
│ │ │ ├── QuickNav.vue
│ │ │ ├── SaleRadar.vue
│ │ │ ├── WorkbenchHeader.vue
│ │ │ └── data.ts
│ │ │ └── index.vue
│ │ ├── develop
│ │ ├── contentType
│ │ │ ├── EditContentTypeDrawer.vue
│ │ │ ├── data.ts
│ │ │ ├── dynamicIndex.json
│ │ │ ├── dynamicIndex.vue
│ │ │ └── index.vue
│ │ ├── listManagement
│ │ │ ├── ListDetails.vue
│ │ │ ├── data.ts
│ │ │ ├── index.vue
│ │ │ └── listPreview.vue
│ │ └── menu
│ │ │ ├── MenuDrawer.vue
│ │ │ ├── index.vue
│ │ │ └── menu.data.ts
│ │ ├── sys
│ │ ├── about
│ │ │ └── index.vue
│ │ ├── exception
│ │ │ └── index.vue
│ │ ├── iframe
│ │ │ ├── FrameBlank.vue
│ │ │ └── index.vue
│ │ ├── lock
│ │ │ ├── index.vue
│ │ │ ├── lock-page.vue
│ │ │ └── useNow.ts
│ │ ├── login
│ │ │ ├── forget-password-form.vue
│ │ │ ├── login copy.vue
│ │ │ ├── login-form copy.vue
│ │ │ ├── login-form-title.vue
│ │ │ ├── login-form.vue
│ │ │ ├── login.vue
│ │ │ ├── loginCallback.vue
│ │ │ ├── logoutcallback.vue
│ │ │ ├── mobile-form.vue
│ │ │ ├── qrcode-form.vue
│ │ │ ├── register-form.vue
│ │ │ ├── session-timeout.vue
│ │ │ └── use-login.ts
│ │ └── redirect
│ │ │ └── index.vue
│ │ └── system
│ │ ├── account
│ │ ├── AccountDetail.vue
│ │ ├── AccountModal.json
│ │ ├── AccountModal.vue
│ │ ├── DeptTree.vue
│ │ ├── account.data.ts
│ │ ├── account.json
│ │ ├── index copy.vue
│ │ └── index.vue
│ │ ├── dept
│ │ ├── DeptModal.vue
│ │ ├── dept.data.ts
│ │ └── index.vue
│ │ ├── password
│ │ ├── index.vue
│ │ └── pwd.data.ts
│ │ └── role
│ │ ├── RoleDrawer.vue
│ │ ├── index.vue
│ │ └── role.data.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ └── vite.config.ts
├── configs
├── css-preprocess
│ ├── package.json
│ ├── postcss.js
│ └── tailwind.js
├── lint
│ ├── commitlint.js
│ ├── eslint.js
│ ├── lintstaged.js
│ ├── package.json
│ ├── prettier.js
│ └── stylelint.js
├── tsconfig
│ ├── base.json
│ ├── package.json
│ └── server.json
└── vite
│ ├── build.config.ts
│ ├── package.json
│ ├── src
│ ├── constants.ts
│ ├── index.ts
│ ├── plugins
│ │ ├── compress.ts
│ │ ├── html.ts
│ │ ├── imagemin.ts
│ │ ├── index.ts
│ │ ├── mock.ts
│ │ ├── svg-icons.ts
│ │ └── visualizer.ts
│ ├── presets
│ │ ├── ant
│ │ │ ├── index.ts
│ │ │ ├── modify-vars.ts
│ │ │ ├── theme-plugin.ts
│ │ │ └── theme.ts
│ │ └── index.ts
│ └── utils
│ │ └── index.ts
│ └── tsconfig.json
├── nswag
├── Templates
│ ├── AxiosClient.liquid
│ ├── Client.Method.Documentation.liquid
│ ├── Client.ProcessResponse.HandleStatusCode.liquid
│ ├── Client.ProcessResponse.ReadBodyEnd.liquid
│ ├── Client.ProcessResponse.ReadBodyStart.liquid
│ ├── Client.ProcessResponse.ReadHeaders.liquid
│ ├── Client.ProcessResponse.Return.liquid
│ ├── Client.ProcessResponse.liquid
│ ├── Client.RequestBody.liquid
│ ├── Client.RequestUrl.liquid
│ ├── File.Utilities.liquid
│ └── File.liquid
├── refresh.bat
└── service.config.nswag
├── package.json
├── packages
├── apis
│ ├── account.ts
│ ├── demo
│ │ ├── account.ts
│ │ ├── cascader.ts
│ │ ├── error.ts
│ │ ├── index.ts
│ │ ├── select.ts
│ │ ├── system.ts
│ │ ├── table.ts
│ │ └── tree.ts
│ ├── develop.ts
│ ├── eoc
│ │ ├── app-service-base.ts
│ │ ├── app-service-proxies.ts
│ │ ├── contentApi.ts
│ │ └── graphqlApi.ts
│ ├── package.json
│ ├── sys
│ │ ├── index.ts
│ │ ├── menu.ts
│ │ ├── upload.ts
│ │ └── user.ts
│ ├── system.ts
│ └── types.ts
├── components
│ ├── antd
│ │ └── package.json
│ └── common
│ │ ├── count-to
│ │ └── index.vue
│ │ ├── icon
│ │ └── index.vue
│ │ ├── index.ts
│ │ ├── package.json
│ │ ├── qrcode
│ │ ├── draw-canvas.ts
│ │ ├── draw-logo.ts
│ │ ├── index.vue
│ │ ├── to-canvas.ts
│ │ └── typing.ts
│ │ ├── svg-icon
│ │ └── index.vue
│ │ ├── time
│ │ └── index.vue
│ │ └── transition
│ │ └── collapse-transition.vue
├── directives
│ ├── bridge.ts
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── auth.ts
│ │ ├── click-outside.ts
│ │ └── loading.ts
├── locale
│ ├── index.ts
│ ├── package.json
│ ├── src
│ │ ├── helper.ts
│ │ ├── lang
│ │ │ ├── en.ts
│ │ │ ├── en
│ │ │ │ ├── common.ts
│ │ │ │ ├── component.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── routes
│ │ │ │ │ ├── basic.ts
│ │ │ │ │ ├── dashboard.ts
│ │ │ │ │ ├── default.ts
│ │ │ │ │ ├── demo.ts
│ │ │ │ │ └── develop.ts
│ │ │ │ └── sys.ts
│ │ │ ├── zh-CN
│ │ │ │ ├── common.ts
│ │ │ │ ├── component.ts
│ │ │ │ ├── layout.ts
│ │ │ │ ├── routes
│ │ │ │ │ ├── amis.ts
│ │ │ │ │ ├── basic.ts
│ │ │ │ │ ├── crm.ts
│ │ │ │ │ ├── dashboard.ts
│ │ │ │ │ ├── default.ts
│ │ │ │ │ ├── demo.ts
│ │ │ │ │ └── develop.ts
│ │ │ │ └── sys.ts
│ │ │ └── zh_CN.ts
│ │ ├── setup-i18n.ts
│ │ ├── store.ts
│ │ ├── use-i18n.ts
│ │ └── use-locale.ts
│ └── tsconfig.json
├── request
│ ├── bridge.ts
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── Axios.ts
│ │ ├── axiosCancel.ts
│ │ ├── axiosTransform.ts
│ │ ├── checkStatus.ts
│ │ ├── helper.ts
│ │ └── index.ts
├── setting
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── component.ts
│ │ ├── design.ts
│ │ ├── index.ts
│ │ ├── locale.ts
│ │ ├── project.ts
│ │ └── site.ts
├── styles
│ ├── common
│ │ ├── color.css
│ │ ├── common.css
│ │ ├── index.ts
│ │ └── tailwind.css
│ └── package.json
├── tokens
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── cache.ts
│ │ ├── enums
│ │ ├── breakpoint.ts
│ │ ├── http.ts
│ │ ├── index.ts
│ │ └── menu.ts
│ │ ├── index.ts
│ │ ├── router.ts
│ │ └── sidebar.ts
├── types
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── OrchardScripts
│ │ ├── OCJavaScriptBackendMethods.ts
│ │ └── OCLiquidFilters.md
│ │ ├── config.ts
│ │ ├── global.ts
│ │ ├── index.ts
│ │ ├── router.ts
│ │ ├── service.ts
│ │ ├── shims
│ │ ├── index.ts
│ │ ├── module.ts
│ │ ├── pinia.ts
│ │ └── vue-router.ts
│ │ ├── store.ts
│ │ └── util.ts
├── use
│ ├── index.ts
│ ├── package.json
│ └── src
│ │ ├── index.ts
│ │ ├── use-attrs.ts
│ │ ├── use-context.ts
│ │ ├── use-pagination.ts
│ │ ├── use-refs.ts
│ │ ├── use-script.ts
│ │ ├── use-title.ts
│ │ ├── use-watermark.ts
│ │ └── use-window-resize.ts
└── utils
│ ├── bem.ts
│ ├── index.ts
│ ├── package.json
│ └── src
│ ├── color.ts
│ ├── config.ts
│ ├── date.ts
│ ├── deep-merge.ts
│ ├── dom.ts
│ ├── event.ts
│ ├── file.ts
│ ├── helper
│ ├── index.ts
│ ├── route.ts
│ ├── slot.ts
│ └── tree.ts
│ ├── index.ts
│ ├── is.ts
│ ├── lifecycle.ts
│ ├── log.ts
│ ├── mitt.ts
│ ├── util.ts
│ ├── uuid.ts
│ └── with-install.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── scripts
├── package.json
└── src
│ ├── build.ts
│ ├── dev.ts
│ └── helper.ts
├── turbo.json
├── vitest.config.ts
└── 问题梳理.md
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "linked": [],
6 | "access": "restricted",
7 | "baseBranch": "next",
8 | "updateInternalDependencies": "patch",
9 | "ignore": []
10 | }
11 |
--------------------------------------------------------------------------------
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/lint/commitlint')
2 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset=utf-8
5 | end_of_line=lf
6 | insert_final_newline=true
7 | indent_style=space
8 | indent_size=2
9 | max_line_length = 100
10 |
11 | [*.{yml,yaml,json}]
12 | indent_style = space
13 | indent_size = 2
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
18 | [Makefile]
19 | indent_style = tab
20 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 |
2 | *.sh
3 | node_modules
4 | *.md
5 | *.woff
6 | *.ttf
7 | .vscode
8 | .idea
9 | dist
10 | public
11 | docs
12 | .husky
13 | .local
14 | bin
15 | Dockerfile
16 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/lint/eslint')
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-feature.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🚀 Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 |
17 |
18 | ### Subject of the feature
19 |
20 | Describe your issue here.
21 |
22 | ### Problem
23 |
24 | If the feature requests relates to a problem, please describe the problem you are trying to solve here.
25 |
26 | ### Expected behaviour
27 |
28 | What should happen? Please describe the desired behaviour.
29 |
30 | ### Alternatives
31 |
32 | What are the alternative solutions? Please describe what else you have considered?
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/3-bug-cn.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug 报告
3 | about: 向我们报告一个Bug以帮助我们改进
4 | title: ''
5 | labels: 'bug: pending triage'
6 | assignees: ''
7 | ---
8 |
9 | **⚠️ 重要 ⚠️ 在进一步操作之前,请检查下列选项。如果您忽视此模板或者没有提供关键信息,您的 Issue 将直接被关闭**
10 |
11 | - [ ] 已阅读 [文档](https://anncwb.github.io/vue-vben-admin-doc/).
12 | - [ ] 确保您的代码已是最新或者所报告的 Bug 在最新版本中可以重现. (部分 Bug 可能已经在最近的代码中修复)
13 | - [ ] 已在 Issues 中搜索了相关的关键词
14 | - [ ] 不是 ant design vue 组件库的 Bug
15 |
16 | ### 描述 Bug
17 |
18 | 请清晰地描述此 Bug 的具体表现。
19 |
20 | ### 复现 Bug
21 |
22 | 请描述在演示页面中复现 Bug 的详细步骤,以确保我们可以理解并定位问题。部分 Bug 如果未在 Demo 中涉及,请务必提供关键代码
23 |
24 | ## 系统信息
25 |
26 | - 操作系统:
27 | - Node 版本:
28 | - 包管理器 (npm/yarn/pnpm) 及其版本:
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Discord Chat
4 | url: https://discord.gg/8GuAdwDhj6
5 | about: Ask questions and discuss with other Vben users in real time.
6 | - name: Questions & Discussions
7 | url: https://github.com/anncwb/vue-vben-admin/discussions
8 | about: Use GitHub discussions for message-board style questions and discussions.
9 |
--------------------------------------------------------------------------------
/.github/contributing.md:
--------------------------------------------------------------------------------
1 | # Contributing Guide
2 |
3 | 1. Make sure you put things in the right category!
4 | 2. Always add your items to the end of a list. To be fair, the order is first-come-first-serve.
5 | 3. If you think something belongs in the wrong category, or think there needs to be a new category, feel free to edit things too.
6 |
--------------------------------------------------------------------------------
/.github/workflows/issue-close-require.yml:
--------------------------------------------------------------------------------
1 | name: Issue Close Require
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *'
6 |
7 | jobs:
8 | close-issues:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: need reproduction
12 | uses: actions-cool/issues-helper@v2.1.1
13 | with:
14 | actions: 'close-issues'
15 | token: ${{ secrets.OPER_TOKEN }}
16 | labels: 'need reproduction'
17 | inactive-day: 3
18 |
--------------------------------------------------------------------------------
/.github/workflows/issue-labeled.yml:
--------------------------------------------------------------------------------
1 | name: Issue Labeled
2 |
3 | on:
4 | issues:
5 | types: [labeled]
6 |
7 | jobs:
8 | reply-labeled:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: remove pending
12 | if: github.event.label.name == 'enhancement' || github.event.label.name == 'bug'
13 | uses: actions-cool/issues-helper@v2.1.1
14 | with:
15 | actions: 'remove-labels'
16 | token: ${{ secrets.OPER_TOKEN }}
17 | issue-number: ${{ github.event.issue.number }}
18 | labels: 'bug: pending triage'
19 |
20 | - name: need reproduction
21 | if: github.event.label.name == 'need reproduction'
22 | uses: actions-cool/issues-helper@v2.1.1
23 | with:
24 | actions: 'create-comment, remove-labels'
25 | token: ${{ secrets.OPER_TOKEN }}
26 | issue-number: ${{ github.event.issue.number }}
27 | body: |
28 | Hello @${{ github.event.issue.user.login }}. Please provide the complete reproduction steps and code. Issues labeled by `need reproduction` will be closed if no activities in 3 days.
29 | labels: 'bug: pending triage'
30 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Create Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - v*
7 |
8 | jobs:
9 | build:
10 | name: Create Release
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout code
14 | uses: actions/checkout@master
15 |
16 | - name: Create Release for Tag
17 | id: release_tag
18 | uses: yyx990803/release-tag@master
19 | env:
20 | GITHUB_TOKEN: ${{ secrets.OPER_TOKEN }}
21 | with:
22 | tag_name: ${{ github.ref }}
23 | body: |
24 | Please refer to [CHANGELOG.md](https://github.com/anncwb/vue-vben-admin/blob/main/CHANGELOG.md) for details.
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | dist
4 | *-dist
5 | .cache
6 |
7 | .turbo
8 | .local
9 | # local env files
10 | .env.local
11 | .env.*.local
12 | .eslintcache
13 |
14 | # Log files
15 | npm-debug.log*
16 | yarn-debug.log*
17 | yarn-error.log*
18 | .pnpm-debug.log*
19 |
20 | # Editor directories and files
21 | .idea
22 | # .vscode
23 | *.suo
24 | *.ntvs*
25 | *.njsproj
26 | *.sln
27 | *.sw?
28 | apps/ant-admin/public/amis-editor-renderer
29 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | ports:
2 | - port: 3344
3 | onOpen: open-preview
4 | tasks:
5 | - init: pnpm install
6 | command: pnpm run dev
7 |
--------------------------------------------------------------------------------
/.lintstagedrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/lint/lintstaged')
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist = true
2 | ignore-workspace-root-check=true
3 | public-hoist-pattern[]=*
4 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | public
4 | .local
5 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/lint/prettier')
2 |
--------------------------------------------------------------------------------
/.stylelintignore:
--------------------------------------------------------------------------------
1 | dist
2 | public
3 | node_modules
4 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/lint/stylelint')
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "vue.volar",
4 | "dbaeumer.vscode-eslint",
5 | "stylelint.vscode-stylelint",
6 | "esbenp.prettier-vscode",
7 | "mrmlnc.vscode-less",
8 | "lokalise.i18n-ally",
9 | "antfu.iconify",
10 | "mikestead.dotenv",
11 | "heybourn.headwind"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "type": "vscode-edge-devtools.debug",
6 | "request": "attach",
7 | "name": "Attach to Microsoft Edge and open the Edge DevTools",
8 | "url": "http://localhost:8080",
9 | "webRoot": "${workspaceFolder}"
10 | },
11 | {
12 | "type": "chrome",
13 | "request": "launch",
14 | "name": "Launch Chrome",
15 | "url": "http://localhost:3000",
16 | "webRoot": "${workspaceFolder}/src",
17 | "sourceMaps": true
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020-present, Vben
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## 基于 Vue Vben Admin 的OC中后台模板
3 |
4 | ### OIDC 授权
5 | - [x] 集成OC登录授权
6 |
7 |
8 |
9 |
10 | 以 vben admin next 分支为基础搭建的 OrchardCore SAP 前端框架
11 |
12 | 服务端:https://github.com/EasyOC/EasyOC
13 |
14 | QQ群:877196442
15 | ## 框架
16 |
17 | - [x] oidc password 授权登录
18 | - [ ] oidc code 授权登录
19 |
20 |
21 | ### 基础信息管理
22 | - [X] 用户列表 (动态属性)
23 | 
24 |
25 | - [X] 用户列表部门筛选 (graphql+lucene)
26 | 
27 |
28 | - [ ] 修改用户信息 (暂时用OC后台编辑,通过配置 UserProfile 类型实现动态属性)
29 | - [ ] 角色管理
30 | - [ ] 部门管理
31 |
32 | ### 通用功能
33 | - [ ] Excel 导入导出
34 | - [ ] 用户自定义列表顺序 (不同用户查看的不同列顺序)
35 |
36 | ### VbenAdmin 代码生成器/自动组件
37 | 
38 | 
39 |
40 |
--------------------------------------------------------------------------------
/README.zh-CN.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/README.zh-CN.md
--------------------------------------------------------------------------------
/apps/amis/.env.development:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/amis/.env.development
--------------------------------------------------------------------------------
/apps/amis/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | gh-pages
64 | /public
65 |
66 | package-lock.json
--------------------------------------------------------------------------------
/apps/amis/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "tabWidth": 4,
4 | "useTabs": false,
5 | "singleQuote": true,
6 | "semi": true,
7 | "trailingComma": "none",
8 | "bracketSpacing": false,
9 | "arrowParens": "avoid",
10 | "jsxBracketSameLine": false
11 | }
12 |
--------------------------------------------------------------------------------
/apps/amis/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14.16.0-alpine3.12
2 |
3 | RUN mkdir -p /etc/amis-editor
4 |
5 | WORKDIR /etc/amis-editor
6 |
7 | COPY . .
8 |
9 | EXPOSE 8082
10 |
11 | ENTRYPOINT [ "npm", "run", "server" ]
12 |
--------------------------------------------------------------------------------
/apps/amis/auth/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 正在登陆...
8 |
9 |
10 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/apps/amis/auth/login.tsx:
--------------------------------------------------------------------------------
1 | import authService from "route/auth/authService";
2 | export function bootstrap() {
3 | authService.login()
4 | }
5 |
--------------------------------------------------------------------------------
/apps/amis/auth/logincallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/apps/amis/auth/logincallback.tsx:
--------------------------------------------------------------------------------
1 | import authService from 'route/auth/authService';
2 | export function bootstrap() {
3 | authService.completeLogin().then(() => {
4 | if (window.opener) {
5 | if (window.localStorage.getItem('needReload') == '1') {
6 | window.localStorage.removeItem('needReload');
7 | const returnUrl = window.localStorage.getItem('returnUrl');
8 | if (returnUrl) {
9 | window.localStorage.removeItem('returnUrl');
10 | window.location.href = returnUrl;
11 | // } else {
12 | // window.opener.location.reload();
13 | }
14 | }
15 | // window.close();
16 | }
17 | });
18 | }
19 |
--------------------------------------------------------------------------------
/apps/amis/deploy-gh-pages.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ -z "$(git status --porcelain)" ]; then
5 | # Working directory clean
6 | echo "Working directory clean"
7 | else
8 | # Uncommitted changes
9 | read -p "You got uncommitted changes, press y to continue? " -n 1 -r
10 | echo # (optional) move to a new line
11 | if [[ ! $REPLY =~ ^[Yy]$ ]]; then
12 | echo "Skiped!"
13 | [[ "$0" == "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell
14 | fi
15 | fi
16 |
17 | rm -rf gh-pages
18 |
19 | fis3 release gh-pages -c
20 |
21 | node ./upload2cdn.js $1
22 |
23 | git add gh-pages -f
24 |
25 | git commit -m "更新 gh-pages"
26 |
27 | git push
28 |
29 | git subtree push --prefix gh-pages origin gh-pages
30 |
31 | git commit -m 'rebuild pages' --allow-empty
32 |
33 | git push origin
34 |
35 | echo "done"
36 |
--------------------------------------------------------------------------------
/apps/amis/index.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @file entry of this example.
3 | */
4 | import React from 'react';
5 | import ReactDom from 'react-dom';
6 | import authService from 'route/auth/authService';
7 | import App from './App';
8 |
9 | export function bootstrap(mountTo: HTMLElement) {
10 | // new login().login().then(() => {
11 | // console.log("authService.completeLogin()");
12 | // })
13 | // authService.signinPopup();
14 | ReactDom.render(, mountTo);
15 | }
16 |
--------------------------------------------------------------------------------
/apps/amis/renderer/MyRenderer.tsx:
--------------------------------------------------------------------------------
1 | import {Renderer} from 'amis';
2 | import { RendererProps } from 'amis/lib/factory';
3 | import React from 'react';
4 |
5 | export interface MyRendererProps extends RendererProps {
6 | target?: string;
7 | }
8 |
9 | @Renderer({
10 | test: /\bmy-renderer$/,
11 | name: 'my-renderer'
12 | })
13 | export default class MyRenderer extends React.Component {
14 | static defaultProps = {
15 | target: 'world'
16 | }
17 |
18 | render() {
19 | const {
20 | target
21 | } = this.props;
22 |
23 | return (
24 | Hello {target}!
25 | );
26 | }
27 | }
--------------------------------------------------------------------------------
/apps/amis/route/NotFound.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Link} from 'react-router-dom';
3 | import {NotFound} from 'amis';
4 |
5 | export default () => (
6 |
9 |
10 |
11 | 去首页
12 |
13 | }
14 | footerText={''}
15 | />
16 | );
17 |
--------------------------------------------------------------------------------
/apps/amis/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "outDir": "output",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "lib": ["es6", "dom"],
9 | "sourceMap": true,
10 | "jsx": "react",
11 | "moduleResolution": "node",
12 | "rootDir": "./",
13 | "noImplicitReturns": true,
14 | "noImplicitThis": true,
15 | "noImplicitAny": true,
16 | "strictNullChecks": true,
17 | "experimentalDecorators": true,
18 | "emitDecoratorMetadata": true,
19 | "allowSyntheticDefaultImports": true,
20 | "typeRoots": ["./node_modules/@types", "./typings"]
21 | },
22 | "include": ["**/*"],
23 | "exclude": ["node_modules", "build", "scripts", "acceptance-tests", "webpack", "jest", "src/setupTests.ts"],
24 | "types": ["typePatches"]
25 | }
26 |
--------------------------------------------------------------------------------
/apps/ant-admin/.env:
--------------------------------------------------------------------------------
1 | # spa title
2 | VITE_GLOB_APP_TITLE = EasyOC Admin
3 |
4 | # spa shortname
5 | VITE_GLOB_APP_SHORT_NAME = easyocvben
6 |
--------------------------------------------------------------------------------
/apps/ant-admin/.env.development:
--------------------------------------------------------------------------------
1 | # Whether to open mock
2 | VITE_USE_MOCK = false
3 |
4 | # public path
5 | VITE_PUBLIC_PATH = /
6 |
7 | # Cross-domain proxy, you can configure multiple
8 | # Please note that no line breaks
9 | # VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]]
10 | # VITE_PROXY=[["/api","https://vvbin.cn/test"]]
11 |
12 | VITE_USE_PWA = true
13 | # Delete console
14 | VITE_DROP_CONSOLE = false
15 |
16 | # Basic interface address SPA
17 | VITE_GLOB_API_URL='http://localhost:2919'
18 |
19 | # Basic interface address OTHERAPI
20 | VITE_GLOB_OTHERAPI_URL='http://localhost:2919'
21 |
22 | # File upload address, optional
23 | VITE_GLOB_UPLOAD_URL=/upload
24 |
25 | VITE_GLOB_amisEditor = 'http://localhost:8082/'
26 | VITE_GLOB_OIDC_clientRoot = 'http://localhost:3000/'
27 | VITE_GLOB_OIDC_stsAuthority = 'http://localhost:2919/'
28 | VITE_GLOB_OIDC_CLIENTID='vue_client_app'
29 |
30 | # Interface prefix
31 | VITE_GLOB_API_URL_PREFIX=
32 |
33 |
34 |
--------------------------------------------------------------------------------
/apps/ant-admin/.env.production:
--------------------------------------------------------------------------------
1 | # Whether to open mock
2 | VITE_USE_MOCK = false
3 |
4 | # public path
5 | VITE_PUBLIC_PATH = /
6 |
7 | # Delete console
8 | VITE_DROP_CONSOLE = true
9 |
10 | # Whether to enable gzip or brotli compression
11 | # Optional: gzip | brotli | none
12 | # If you need multiple forms, you can use `,` to separate
13 | VITE_BUILD_COMPRESS = 'none'
14 |
15 | # Whether to delete origin files when using compress, default false
16 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
17 |
18 | # Basic interface address SPA
19 | VITE_GLOB_API_URL='https://easyoc.netabp.com'
20 |
21 | # File upload address, optional
22 | # It can be forwarded by nginx or write the actual address directly
23 | VITE_GLOB_UPLOAD_URL=/upload
24 |
25 | # Interface prefix
26 | VITE_GLOB_API_URL_PREFIX=
27 |
28 | # Whether to enable image compression
29 | VITE_USE_IMAGEMIN= true
30 |
31 | # use pwa
32 | # VITE_USE_PWA = false
33 |
34 | # Is it compatible with older browsers
35 | # VITE_LEGACY = false
36 | VITE_GLOB_amisEditor = 'https://easyoc.netabp.com/'
37 | VITE_GLOB_OIDC_CLIENTID='vue_client_app'
38 | VITE_GLOB_OTHERAPI_URL='https://easyoc.netabp.com/'
39 | VITE_GLOB_OIDC_clientRoot = 'https://easyocvben.netabp.com/'
40 | VITE_GLOB_OIDC_stsAuthority = 'https://easyoc.netabp.com/'
41 |
--------------------------------------------------------------------------------
/apps/ant-admin/.env.staging:
--------------------------------------------------------------------------------
1 | # Whether to open mock
2 | VITE_USE_MOCK = true
3 | NODE_ENV=staging
4 | # public path
5 | VITE_PUBLIC_PATH = /
6 |
7 | # Cross-domain proxy, you can configure multiple
8 | # Please note that no line breaks
9 | # VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]]
10 | # VITE_PROXY=[["/api","https://vvbin.cn/test"]]
11 |
12 | # Delete console
13 | VITE_DROP_CONSOLE = false
14 |
15 | # Basic interface address SPA
16 | VITE_GLOB_API_URL='https://easyoc.netabp.com'
17 |
18 | # Basic interface address OTHERAPI
19 | VITE_GLOB_OTHERAPI_URL='https://easyoc.netabp.com'
20 |
21 | # File upload address, optional
22 | VITE_GLOB_UPLOAD_URL=/upload
23 |
24 | VITE_GLOB_OIDC_clientRoot = 'http://localhost:3000/'
25 | VITE_GLOB_OIDC_stsAuthority = 'https://easyoc.netabp.com/'
26 | VITE_GLOB_OIDC_CLIENTID='vue_client_app'
27 |
28 | # Interface prefix
29 | VITE_GLOB_API_URL_PREFIX=
30 |
31 |
32 |
--------------------------------------------------------------------------------
/apps/ant-admin/.env.test:
--------------------------------------------------------------------------------
1 | NODE_ENV=production
2 |
3 | # Whether to open mock
4 | VITE_USE_MOCK = true
5 |
6 | # public path
7 | VITE_PUBLIC_PATH = /
8 |
9 | # Delete console
10 | VITE_DROP_CONSOLE = true
11 |
12 | # Whether to enable gzip or brotli compression
13 | # Optional: gzip | brotli | none
14 | # If you need multiple forms, you can use `,` to separate
15 | VITE_BUILD_COMPRESS = 'none'
16 |
17 | # Whether to delete origin files when using compress, default false
18 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false
19 |
20 | # Basic interface address SPA
21 | VITE_GLOB_API_URL=/basic-api
22 |
23 | # File upload address, optional
24 | # It can be forwarded by nginx or write the actual address directly
25 | VITE_GLOB_UPLOAD_URL=/upload
26 |
27 | # Whether to enable image compression
28 | VITE_USE_IMAGEMIN= true
29 |
30 | # use pwa
31 | VITE_USE_PWA = false
32 |
33 | # Is it compatible with older browsers
34 | VITE_LEGACY = false
35 |
--------------------------------------------------------------------------------
/apps/ant-admin/mock/_mock-server.ts:
--------------------------------------------------------------------------------
1 | import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'
2 |
3 | const modules = import.meta.globEager('./**/*.ts')
4 |
5 | const mockModules: any[] = []
6 | Object.keys(modules).forEach((key) => {
7 | if (key.includes('/_')) {
8 | return
9 | }
10 | mockModules.push(...modules[key].default)
11 | })
12 |
13 | /**
14 | * Used in a production environment. Need to manually import all modules
15 | */
16 | export const setupProdMockServer = () => createProdMockServer(mockModules)
17 |
--------------------------------------------------------------------------------
/apps/ant-admin/mock/demo/select-demo.ts:
--------------------------------------------------------------------------------
1 | import { MockMethod } from 'vite-plugin-mock'
2 | import { resultSuccess } from '../_util'
3 |
4 | const demoList = (keyword, count = 20) => {
5 | const result = {
6 | list: [] as any[],
7 | }
8 | for (let index = 0; index < count; index++) {
9 | result.list.push({
10 | name: `${keyword ?? ''}选项${index}`,
11 | id: `${index}`,
12 | })
13 | }
14 | return result
15 | }
16 |
17 | export default [
18 | {
19 | url: '/basic-api/select/getDemoOptions',
20 | timeout: 1000,
21 | method: 'get',
22 | response: ({ query }) => {
23 | const { keyword, count } = query
24 | console.log(keyword)
25 | return resultSuccess(demoList(keyword, count))
26 | },
27 | },
28 | ] as MockMethod[]
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/mock/demo/tree-demo.ts:
--------------------------------------------------------------------------------
1 | import { MockMethod } from 'vite-plugin-mock'
2 | import { resultSuccess } from '../_util'
3 |
4 | const demoTreeList = (keyword) => {
5 | const result = {
6 | list: [] as Recordable[],
7 | }
8 | for (let index = 0; index < 5; index++) {
9 | const children: Recordable[] = []
10 | for (let j = 0; j < 3; j++) {
11 | children.push({
12 | title: `${keyword ?? ''}选项${index}-${j}`,
13 | value: `${index}-${j}`,
14 | key: `${index}-${j}`,
15 | })
16 | }
17 | result.list.push({
18 | title: `${keyword ?? ''}选项${index}`,
19 | value: `${index}`,
20 | key: `${index}`,
21 | children,
22 | })
23 | }
24 | return result
25 | }
26 |
27 | export default [
28 | {
29 | url: '/basic-api/tree/getDemoOptions',
30 | timeout: 1000,
31 | method: 'get',
32 | response: ({ query }) => {
33 | const { keyword } = query
34 | console.log(keyword)
35 | return resultSuccess(demoTreeList(keyword))
36 | },
37 | },
38 | ] as MockMethod[]
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/css-preprocess/postcss')
2 |
--------------------------------------------------------------------------------
/apps/ant-admin/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/favicon.ico
--------------------------------------------------------------------------------
/apps/ant-admin/public/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/img/logo.png
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/resource/img/logo.png
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/img/pwa-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/resource/img/pwa-192x192.png
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/img/pwa-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/resource/img/pwa-512x512.png
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/tinymce/skins/ui/oxide-dark/content.mobile.min.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 | * Licensed under the LGPL or a commercial license.
4 | * For LGPL see License.txt in the project root for license information.
5 | * For commercial licenses see https://www.tiny.cloud/
6 | */
7 | .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position: absolute;display: inline-block;background-color: green;opacity: .5;}
8 |
9 | body{-webkit-text-size-adjust: none;}
10 |
11 | body img{max-width: 96vw;}
12 |
13 | body table img{max-width: 95%;}
14 |
15 | body{font-family: sans-serif;}
16 |
17 | table{border-collapse: collapse;}
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/tinymce/skins/ui/oxide/content.mobile.min.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 | * Licensed under the LGPL or a commercial license.
4 | * For LGPL see License.txt in the project root for license information.
5 | * For commercial licenses see https://www.tiny.cloud/
6 | */
7 | .tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{position: absolute;display: inline-block;background-color: green;opacity: .5;}
8 |
9 | body{-webkit-text-size-adjust: none;}
10 |
11 | body img{max-width: 96vw;}
12 |
13 | body table img{max-width: 95%;}
14 |
15 | body{font-family: sans-serif;}
16 |
17 | table{border-collapse: collapse;}
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/public/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/public/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff
--------------------------------------------------------------------------------
/apps/ant-admin/scripts/post-build.ts:
--------------------------------------------------------------------------------
1 | // #!/usr/bin/env node
2 |
3 | import { runBuildConfig } from './build-config'
4 | import { cyan, red } from 'picocolors'
5 | import pkg from '../package.json'
6 |
7 | export const runBuild = async () => {
8 | try {
9 | const argvList = process.argv.splice(2)
10 |
11 | // Generate configuration file
12 | if (!argvList.includes('disabled-config')) {
13 | runBuildConfig()
14 | }
15 |
16 | console.log(`✨ ${cyan(`[${pkg.name}]`)}` + ' - build successfully!')
17 | } catch (error) {
18 | console.log(red('vite build error:\n' + error))
19 | process.exit(1)
20 | }
21 | }
22 | runBuild()
23 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/api/ocUtils.ts:
--------------------------------------------------------------------------------
1 | import { FormSchema } from "@/components/form"
2 | import { clone, get, has, set } from "@pkg/utils"
3 |
4 | export function expandComplexModel(model: any, schemas: FormSchema[]) {
5 | //克隆新的对象
6 | const res: any = clone(model)
7 | //复杂对象展开
8 | schemas.filter(x => x.fieldMap && !!x.fieldMap.mapTo).forEach((schema) => {
9 | if (schema.fieldMap) {
10 | const item = schema.fieldMap
11 | if (has(res, item.mapTo)) {
12 | res[schema.field] = get(res, item.mapTo)
13 | }
14 | }
15 | })
16 | console.log("expanded model", res)
17 | return res
18 | }
19 |
20 | export function restoreComplexModel(model: any, schemas: FormSchema[]) {
21 | //克隆为新的对象,避免保存失败后,原对象被修改
22 | const res: any = clone(model) //复杂对象恢复
23 | schemas.filter(x => x.fieldMap && !!x.fieldMap.mapTo)
24 | .forEach(schema => {
25 | if (schema.fieldMap) {
26 | set(res, schema.fieldMap.mapTo, res[schema.field])
27 | }
28 | })
29 | console.log(res, "NewData")
30 | return res
31 | }
--------------------------------------------------------------------------------
/apps/ant-admin/src/app.vue:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/assets/images/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/src/assets/images/demo.png
--------------------------------------------------------------------------------
/apps/ant-admin/src/assets/images/header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/src/assets/images/header.jpg
--------------------------------------------------------------------------------
/apps/ant-admin/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/apps/ant-admin/src/assets/images/logo.png
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Amis/index.ts:
--------------------------------------------------------------------------------
1 | // import { useAppStore } from '@/store/app'
2 | import { withInstall } from '@pkg/utils'
3 | // const appStore = useAppStore()
4 |
5 | import AmisSdk from './src/index.vue'
6 | export const Amis = withInstall(AmisSdk)
7 |
8 | // import veauryAMISRenderer from './src/veauryAMISRenderer.vue'
9 | // const mode = appStore.projectConfig?.amisRenderMode != "react" ? "sdk" : "react"
10 | // console.warn(`Amis 当前正在使用${mode}渲染器`)
11 | // export const Amis = mode != "react" ? withInstall(AmisSdk) : withInstall(veauryAMISRenderer)
12 | // export const Amis = withInstall(veauryAMISRenderer)
13 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Amis/src/vue/AA.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | The Vue component will disappear in {{$attrs.disappearTime}}s
4 |
5 |
6 |
7 |
16 |
17 |
20 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Amis/src/vue/Basic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
This is the Vue Component.
4 | received foo's value: {{$attrs.foo}}
5 |
6 |
7 |
8 |
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Authority/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import authority from './src/index.vue'
3 |
4 | export const Authority = withInstall(authority)
5 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/CodeEditor/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import codeEditor from './src/CodeEditor.vue';
3 | import jsonPreview from './src/json-preview/JsonPreview.vue';
4 |
5 | export const CodeEditor = withInstall(codeEditor);
6 | export const JsonPreview = withInstall(jsonPreview);
7 |
8 | export * from './src/typing';
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/CodeEditor/src/codemirror/codeMirror.ts:
--------------------------------------------------------------------------------
1 | import CodeMirror from 'codemirror';
2 | import './codemirror.css';
3 | import 'codemirror/theme/idea.css';
4 | import 'codemirror/theme/material-palenight.css';
5 | // import 'codemirror/addon/lint/lint.css';
6 |
7 | // modes
8 | import 'codemirror/mode/javascript/javascript';
9 | import 'codemirror/mode/css/css';
10 | import 'codemirror/mode/htmlmixed/htmlmixed';
11 | // addons
12 | // import 'codemirror/addon/edit/closebrackets';
13 | // import 'codemirror/addon/edit/closetag';
14 | // import 'codemirror/addon/comment/comment';
15 | // import 'codemirror/addon/fold/foldcode';
16 | // import 'codemirror/addon/fold/foldgutter';
17 | // import 'codemirror/addon/fold/brace-fold';
18 | // import 'codemirror/addon/fold/indent-fold';
19 | // import 'codemirror/addon/lint/json-lint';
20 | // import 'codemirror/addon/fold/comment-fold';
21 | export { CodeMirror };
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/CodeEditor/src/json-preview/JsonPreview.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/CodeEditor/src/typing.ts:
--------------------------------------------------------------------------------
1 | export enum MODE {
2 | JSON = 'application/json',
3 | HTML = 'htmlmixed',
4 | JS = 'javascript',
5 | }
6 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/OrchardCore/index.ts:
--------------------------------------------------------------------------------
1 | import ContentForm from './src/ContentForm.vue'
2 |
3 | export { ContentForm }
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/OrchardCore/src/props.ts:
--------------------------------------------------------------------------------
1 | import type { PropType } from 'vue'
2 |
3 | export const basicProps = {
4 | contentItemId: {
5 | type: String as PropType,
6 | require: true,
7 | },
8 | /**
9 | * 类型名称
10 | */
11 | typeName: {
12 | type: String as PropType,
13 | default: '',
14 | },
15 | }
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/OrchardCore/types/ContentFormProps.ts:
--------------------------------------------------------------------------------
1 | export interface ContentFormProps {
2 | contentItemId: string
3 | /**
4 | * 类型名称
5 | */
6 | typeName: string
7 | }
8 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Tree/index.ts:
--------------------------------------------------------------------------------
1 | import BasicTree from './src/index.vue'
2 | import './style'
3 |
4 | export { BasicTree }
5 | export type { ContextMenuItem } from '@/hooks/web/useContextMenu'
6 | export * from './src/tree'
7 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Tree/src/tree-icon.ts:
--------------------------------------------------------------------------------
1 | import type { VNode, FunctionalComponent } from 'vue'
2 | import { h } from 'vue'
3 | import { isString } from '@pkg/utils'
4 | import { Icon } from '@components/common'
5 |
6 | export const TreeIcon: FunctionalComponent = ({
7 | icon,
8 | }: {
9 | icon: VNode | string
10 | }) => {
11 | if (!icon) return null
12 | if (isString(icon)) {
13 | return h(Icon, { icon, class: 'mr-1' })
14 | }
15 | return Icon
16 | }
17 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Tree/style/index.less:
--------------------------------------------------------------------------------
1 | @tree-prefix-cls: ~'@{namespace}-tree';
2 |
3 | .@{tree-prefix-cls} {
4 | background-color: @component-background;
5 |
6 | .ant-tree-node-content-wrapper {
7 | position: relative;
8 |
9 | .ant-tree-title {
10 | position: absolute;
11 | left: 0;
12 | width: 100%;
13 | overflow: hidden;
14 | text-overflow: ellipsis;
15 | white-space: nowrap;
16 | }
17 | }
18 |
19 | &__title {
20 | position: relative;
21 | display: flex;
22 | align-items: center;
23 | width: 100%;
24 | padding-right: 10px;
25 |
26 | &:hover {
27 | .@{tree-prefix-cls}__action {
28 | visibility: visible;
29 | }
30 | }
31 | }
32 |
33 | &__content {
34 | overflow: hidden;
35 | }
36 |
37 | &__actions {
38 | position: absolute;
39 | //top: 2px;
40 | right: 3px;
41 | display: flex;
42 | }
43 |
44 | &__action {
45 | margin-left: 4px;
46 | visibility: hidden;
47 | }
48 |
49 | &-header {
50 | border-bottom: 1px solid @border-color-base;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Tree/style/index.ts:
--------------------------------------------------------------------------------
1 | import './index.less'
2 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Upload/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import basicUpload from './src/index.vue'
3 |
4 | export const BasicUpload = withInstall(basicUpload)
5 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Upload/src/helper.ts:
--------------------------------------------------------------------------------
1 | export function checkFileType(file: File, accepts: string[]) {
2 | const newTypes = accepts.join('|')
3 | // const reg = /\.(jpg|jpeg|png|gif|txt|doc|docx|xls|xlsx|xml)$/i;
4 | const reg = new RegExp('\\.(' + newTypes + ')$', 'i')
5 |
6 | return reg.test(file.name)
7 | }
8 |
9 | export function checkImgType(file: File) {
10 | return isImgTypeByName(file.name)
11 | }
12 |
13 | export function isImgTypeByName(name: string) {
14 | return /\.(jpg|jpeg|png|gif)$/i.test(name)
15 | }
16 |
17 | export function getBase64WithFile(file: File) {
18 | return new Promise<{
19 | result: string
20 | file: File
21 | }>((resolve, reject) => {
22 | const reader = new FileReader()
23 | reader.readAsDataURL(file)
24 | reader.onload = () => resolve({ result: reader.result as string, file })
25 | reader.onerror = (error) => reject(error)
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/Upload/src/thumb-url.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
18 |
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/application/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 |
3 | import appLogo from './src/AppLogo.vue'
4 | import appProvider from './src/AppProvider.vue'
5 | import appSearch from './src/search/AppSearch.vue'
6 | import appLocalePicker from './src/AppLocalePicker.vue'
7 | import appDarkModeToggle from './src/AppDarkModeToggle.vue'
8 |
9 | export { useAppProviderContext } from './src/useAppContext'
10 |
11 | export const AppLogo = withInstall(appLogo)
12 | export const AppProvider = withInstall(appProvider)
13 | export const AppSearch = withInstall(appSearch)
14 | export const AppLocalePicker = withInstall(appLocalePicker)
15 | export const AppDarkModeToggle = withInstall(appDarkModeToggle)
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/application/src/search/AppSearch.vue:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/application/src/search/AppSearchKeyItem.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/application/src/useAppContext.ts:
--------------------------------------------------------------------------------
1 | import { InjectionKey, Ref } from 'vue'
2 | import { createContext, useContext } from '@pkg/use'
3 |
4 | export interface AppProviderContextProps {
5 | prefixCls: Ref
6 | isMobile: Ref
7 | }
8 |
9 | const key: InjectionKey = Symbol()
10 |
11 | export function createAppProviderContext(context: AppProviderContextProps) {
12 | return createContext(context, key)
13 | }
14 |
15 | export function useAppProviderContext() {
16 | return useContext(key)
17 | }
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/basic/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import basicArrow from './src/BasicArrow.vue'
3 | import basicTitle from './src/BasicTitle.vue'
4 | import basicHelp from './src/BasicHelp.vue'
5 |
6 | export const BasicArrow = withInstall(basicArrow)
7 | export const BasicTitle = withInstall(basicTitle)
8 | export const BasicHelp = withInstall(basicHelp)
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/button/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import popConfirmButton from './src/PopConfirmButton.vue'
3 |
4 | export const PopConfirmButton = withInstall(popConfirmButton)
5 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/card-list/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import cardList from './src/CardList.vue'
3 |
4 | export const CardList = withInstall(cardList)
5 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/card-list/src/data.ts:
--------------------------------------------------------------------------------
1 | import { ref } from 'vue'
2 | // 每行个数
3 | export const grid = ref(12)
4 | // slider属性
5 | export const useSlider = (min = 6, max = 12) => {
6 | // 每行显示个数滑动条
7 | const getMarks = () => {
8 | const l = {}
9 | for (let i = min; i < max + 1; i++) {
10 | l[i] = {
11 | style: {
12 | color: '#fff',
13 | },
14 | label: i,
15 | }
16 | }
17 | return l
18 | }
19 | return {
20 | min,
21 | max,
22 | marks: getMarks(),
23 | step: 1,
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/container/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import collapseContainer from './src/collapse/CollapseContainer.vue'
3 | import scrollContainer from './src/ScrollContainer.vue'
4 |
5 | export const CollapseContainer = withInstall(collapseContainer)
6 | export const ScrollContainer = withInstall(scrollContainer)
7 |
8 | export * from './src/typing'
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/container/src/collapse/CollapseHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ title }}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/container/src/typing.ts:
--------------------------------------------------------------------------------
1 | export type ScrollType = 'default' | 'main'
2 |
3 | export interface CollapseContainerOptions {
4 | canExpand?: boolean
5 | title?: string
6 | helpMessage?: Array | string
7 | }
8 | export interface ScrollContainerOptions {
9 | enableScroll?: boolean
10 | type?: ScrollType
11 | }
12 |
13 | export type ScrollActionType = Nullable<{
14 | scrollBottom: () => void
15 | getScrollWrap: () => Nullable
16 | scrollTo: (top: number) => void
17 | }>
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/context-menu/index.ts:
--------------------------------------------------------------------------------
1 | export { createContextMenu, destroyContextMenu } from './src/createContextMenu'
2 |
3 | export * from './src/typing'
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/context-menu/src/typing.ts:
--------------------------------------------------------------------------------
1 | export interface Axis {
2 | x: number
3 | y: number
4 | }
5 |
6 | export interface ContextMenuItem {
7 | label: string
8 | icon?: string
9 | disabled?: boolean
10 | handler?: AnyFunction
11 | divider?: boolean
12 | children?: ContextMenuItem[]
13 | }
14 | export interface CreateContextOptions {
15 | event: MouseEvent
16 | icon?: string
17 | styles?: any
18 | items?: ContextMenuItem[]
19 | }
20 |
21 | export interface ContextMenuProps {
22 | event?: MouseEvent
23 | styles?: any
24 | items: ContextMenuItem[]
25 | customEvent?: MouseEvent
26 | axis?: Axis
27 | width?: number
28 | showIcon?: boolean
29 | }
30 |
31 | export interface ItemContentProps {
32 | showIcon: boolean | undefined
33 | item: ContextMenuItem
34 | handler: AnyFunction
35 | }
36 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/count-down/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import countButton from './src/CountButton.vue'
3 | import countdownInput from './src/CountdownInput.vue'
4 |
5 | export const CountdownInput = withInstall(countdownInput)
6 | export const CountButton = withInstall(countButton)
7 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/count-down/src/useCountdown.ts:
--------------------------------------------------------------------------------
1 | import { ref, unref } from 'vue'
2 | import { tryOnUnmounted } from '@pkg/utils'
3 |
4 | export function useCountdown(count: number) {
5 | const currentCount = ref(count)
6 |
7 | const isStart = ref(false)
8 |
9 | let timerId: ReturnType | null
10 |
11 | function clear() {
12 | timerId && window.clearInterval(timerId)
13 | }
14 |
15 | function stop() {
16 | isStart.value = false
17 | clear()
18 | timerId = null
19 | }
20 |
21 | function start() {
22 | if (unref(isStart) || !!timerId) {
23 | return
24 | }
25 | isStart.value = true
26 | timerId = setInterval(() => {
27 | if (unref(currentCount) === 1) {
28 | stop()
29 | currentCount.value = count
30 | } else {
31 | currentCount.value -= 1
32 | }
33 | }, 1000)
34 | }
35 |
36 | function reset() {
37 | currentCount.value = count
38 | stop()
39 | }
40 |
41 | function restart() {
42 | reset()
43 | start()
44 | }
45 |
46 | tryOnUnmounted(() => {
47 | reset()
48 | })
49 |
50 | return { start, reset, restart, clear, stop, currentCount, isStart }
51 | }
52 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/cropper/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import cropperImage from './src/Cropper.vue'
3 | import avatarCropper from './src/CropperAvatar.vue'
4 |
5 | export * from './src/typing'
6 | export const CropperImage = withInstall(cropperImage)
7 | export const CropperAvatar = withInstall(avatarCropper)
8 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/cropper/src/typing.ts:
--------------------------------------------------------------------------------
1 | import type Cropper from 'cropperjs'
2 |
3 | export interface CropendResult {
4 | imgBase64: string
5 | imgInfo: Cropper.Data
6 | }
7 |
8 | export type { Cropper }
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/description/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import description from './src/Description.vue'
3 |
4 | export * from './src/typing'
5 | export { useDescription } from './src/useDescription'
6 | export const Description = withInstall(description)
7 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/description/src/useDescription.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | DescriptionProps,
3 | DescInstance,
4 | UseDescReturnType,
5 | } from './typing'
6 | import { ref, getCurrentInstance, unref } from 'vue'
7 |
8 | export function useDescription(
9 | props?: Partial,
10 | ): UseDescReturnType {
11 | if (!getCurrentInstance()) {
12 | throw new Error(
13 | 'useDescription() can only be used inside setup() or functional components!',
14 | )
15 | }
16 | const desc = ref>(null)
17 | const loaded = ref(false)
18 |
19 | function register(instance: DescInstance) {
20 | if (unref(loaded) && import.meta.env.PROD) {
21 | return
22 | }
23 | desc.value = instance
24 | props && instance.setDescProps(props)
25 | loaded.value = true
26 | }
27 |
28 | const methods: DescInstance = {
29 | setDescProps: (descProps: Partial): void => {
30 | unref(desc)?.setDescProps(descProps)
31 | },
32 | }
33 |
34 | return [register, methods]
35 | }
36 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/drawer/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import basicDrawer from './src/BasicDrawer.vue'
3 |
4 | export const BasicDrawer = withInstall(basicDrawer)
5 | export * from './src/typing'
6 | export { useDrawer, useDrawerInner } from './src/useDrawer'
7 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/dropdown/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import dropdown from './src/Dropdown.vue'
3 |
4 | export * from './src/typing'
5 | export const Dropdown = withInstall(dropdown)
6 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/dropdown/src/typing.ts:
--------------------------------------------------------------------------------
1 | export interface DropMenu {
2 | onClick?: AnyFunction
3 | to?: string
4 | icon?: string
5 | event: string | number
6 | text: string
7 | disabled?: boolean
8 | divider?: boolean
9 | }
10 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/form/index.ts:
--------------------------------------------------------------------------------
1 | import BasicForm from './src/BasicForm.vue'
2 |
3 | export * from './src/types/form'
4 | export * from './src/types/formItem'
5 |
6 | export { useComponentRegister } from './src/hooks/useComponentRegister'
7 | export { useForm } from './src/hooks/useForm'
8 |
9 | export { default as ApiSelect } from './src/components/ApiSelect.vue'
10 | export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'
11 | export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'
12 | export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue'
13 | export { default as ApiCascader } from './src/components/ApiCascader.vue'
14 |
15 | export { BasicForm }
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/form/src/hooks/useComponentRegister.ts:
--------------------------------------------------------------------------------
1 | import type { ComponentType } from '../types/index'
2 | import { tryOnUnmounted } from '@pkg/utils'
3 | import { add, del } from '../componentMap'
4 | import type { Component } from 'vue'
5 |
6 | export function useComponentRegister(compName: ComponentType, comp: Component) {
7 | add(compName, comp)
8 | tryOnUnmounted(() => {
9 | del(compName)
10 | })
11 | }
12 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/form/src/hooks/useFormContext.ts:
--------------------------------------------------------------------------------
1 | import type { InjectionKey } from 'vue'
2 | import { createContext, useContext } from '@pkg/use'
3 |
4 | export interface FormContextProps {
5 | resetAction: () => Promise
6 | submitAction: () => Promise
7 | }
8 |
9 | const key: InjectionKey = Symbol()
10 |
11 | export function createFormContext(context: FormContextProps) {
12 | return createContext(context, key)
13 | }
14 |
15 | export function useFormContext() {
16 | return useContext(key)
17 | }
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/form/src/types/hooks.ts:
--------------------------------------------------------------------------------
1 | export interface AdvanceState {
2 | isAdvanced: boolean
3 | hideAdvanceBtn: boolean
4 | isLoad: boolean
5 | actionSpan: number
6 | }
7 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/icon/index.ts:
--------------------------------------------------------------------------------
1 | import IconPicker from './src/IconPicker.vue'
2 |
3 | export { IconPicker }
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/loading/index.ts:
--------------------------------------------------------------------------------
1 | import Loading from './src/Loading.vue'
2 |
3 | export { Loading }
4 | export { useLoading } from './src/useLoading'
5 | export { createLoading } from './src/createLoading'
6 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/loading/src/typing.ts:
--------------------------------------------------------------------------------
1 | import { ComponentSizeEnum } from '@pkg/tokens'
2 |
3 | export interface LoadingProps {
4 | tip: string
5 | size: ComponentSizeEnum
6 | absolute: boolean
7 | loading: boolean
8 | background: string
9 | theme: 'dark' | 'light'
10 | }
11 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/menu/index.ts:
--------------------------------------------------------------------------------
1 | import BasicMenu from './src/BasicMenu.vue'
2 |
3 | export { BasicMenu }
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/menu/src/components/BasicMenuItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
21 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/menu/src/components/MenuItemContent.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 | {{ getI18nName }}
10 |
11 |
12 |
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/menu/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface MenuState {
2 | // 默认选中的列表
3 | defaultSelectedKeys: string[]
4 |
5 | // 模式
6 | // mode: MenuModeEnum;
7 |
8 | // // 主题
9 | // theme: ComputedRef | ThemeEnum;
10 |
11 | // 缩进
12 | inlineIndent?: number
13 |
14 | // 展开数组
15 | openKeys: string[]
16 |
17 | // 当前选中的菜单项 key 数组
18 | selectedKeys: string[]
19 |
20 | // 收缩状态下展开的数组
21 | collapsedOpenKeys: string[]
22 | }
23 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/modal/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 | import './src/index.less'
3 | import basicModal from './src/BasicModal.vue'
4 |
5 | export const BasicModal = withInstall(basicModal)
6 | export { useModalContext } from './src/hooks/useModalContext'
7 | export { useModal, useModalInner } from './src/hooks/useModal'
8 | export * from './src/typing'
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/modal/src/components/Modal.tsx:
--------------------------------------------------------------------------------
1 | import { Modal } from 'ant-design-vue'
2 | import { defineComponent, toRefs, unref } from 'vue'
3 | import { basicProps } from '../props'
4 | import { useModalDragMove } from '../hooks/useModalDrag'
5 | import { useAttrs } from '@pkg/use'
6 | import { extendSlots } from '@pkg/utils'
7 |
8 | export default defineComponent({
9 | name: 'Modal',
10 | inheritAttrs: false,
11 | props: basicProps,
12 | emits: ['cancel'],
13 | setup(props, { slots, emit }) {
14 | const { visible, draggable, destroyOnClose } = toRefs(props)
15 | const attrs = useAttrs()
16 | useModalDragMove({
17 | visible,
18 | destroyOnClose,
19 | draggable,
20 | })
21 |
22 | const onCancel = (e: Event) => {
23 | emit('cancel', e)
24 | }
25 |
26 | return () => {
27 | const propsData = { ...unref(attrs), ...props, onCancel } as Recordable
28 | return {extendSlots(slots)}
29 | }
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/modal/src/components/ModalFooter.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 | {{ cancelText }}
10 |
11 |
12 |
19 | {{ okText }}
20 |
21 |
22 |
23 |
24 |
45 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/modal/src/components/ModalHeader.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ title }}
4 |
5 |
6 |
23 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/modal/src/hooks/useModalContext.ts:
--------------------------------------------------------------------------------
1 | import { InjectionKey } from 'vue'
2 | import { createContext, useContext } from '@pkg/use'
3 |
4 | export interface ModalContextProps {
5 | redoModalHeight: () => void
6 | }
7 |
8 | const key: InjectionKey = Symbol()
9 |
10 | export function createModalContext(context: ModalContextProps) {
11 | return createContext(context, key)
12 | }
13 |
14 | export function useModalContext() {
15 | return useContext(key)
16 | }
17 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/page/index.ts:
--------------------------------------------------------------------------------
1 | import { withInstall } from '@pkg/utils'
2 |
3 | import pageFooter from './src/PageFooter.vue'
4 | import pageWrapper from './src/PageWrapper.vue'
5 |
6 | export const PageFooter = withInstall(pageFooter)
7 | export const PageWrapper = withInstall(pageWrapper)
8 |
9 | export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight'
10 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/scrollbar/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * copy from element-ui
3 | */
4 |
5 | import Scrollbar from './src/Scrollbar.vue'
6 |
7 | export { Scrollbar }
8 | export type { ScrollbarType } from './src/types'
9 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/scrollbar/src/types.d.ts:
--------------------------------------------------------------------------------
1 | export interface BarMapItem {
2 | offset: string
3 | scroll: string
4 | scrollSize: string
5 | size: string
6 | key: string
7 | axis: string
8 | client: string
9 | direction: string
10 | }
11 | export interface BarMap {
12 | vertical: BarMapItem
13 | horizontal: BarMapItem
14 | }
15 |
16 | export interface ScrollbarType {
17 | wrap: ElRef
18 | }
19 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/simple-menu/index.ts:
--------------------------------------------------------------------------------
1 | export { default as SimpleMenu } from './src/SimpleMenu.vue'
2 | export { default as SimpleMenuTag } from './src/SimpleMenuTag.vue'
3 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/simple-menu/src/components/types.ts:
--------------------------------------------------------------------------------
1 | import { Ref } from 'vue'
2 |
3 | export interface Props {
4 | theme: string
5 | activeName?: string | number | undefined
6 | openNames: string[]
7 | accordion: boolean
8 | width: string
9 | collapsedWidth: string
10 | indentSize: number
11 | collapse: boolean
12 | activeSubMenuNames: (string | number)[]
13 | }
14 |
15 | export interface SubMenuProvider {
16 | addSubMenu: (name: string | number, update?: boolean) => void
17 | removeSubMenu: (name: string | number, update?: boolean) => void
18 | removeAll: () => void
19 | sliceIndex: (index: number) => void
20 | isRemoveAllPopup: Ref
21 | getOpenNames: () => (string | number)[]
22 | handleMouseleave?: AnyFunction
23 | level: number
24 | props: Props
25 | }
26 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/simple-menu/src/components/useSimpleMenuContext.ts:
--------------------------------------------------------------------------------
1 | import type { InjectionKey, Ref } from 'vue'
2 | import type { Emitter } from '@pkg/utils'
3 | import { createContext, useContext } from '@pkg/use'
4 |
5 | export interface SimpleRootMenuContextProps {
6 | rootMenuEmitter: Emitter
7 | activeName: Ref
8 | }
9 |
10 | const key: InjectionKey = Symbol()
11 |
12 | export function createSimpleRootMenuContext(
13 | context: SimpleRootMenuContextProps,
14 | ) {
15 | return createContext(context, key, {
16 | readonly: false,
17 | native: true,
18 | })
19 | }
20 |
21 | export function useSimpleRootMenuContext() {
22 | return useContext(key)
23 | }
24 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/simple-menu/src/types.ts:
--------------------------------------------------------------------------------
1 | export interface MenuState {
2 | activeName: string
3 | openNames: string[]
4 | activeSubMenuNames: string[]
5 | }
6 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/index.ts:
--------------------------------------------------------------------------------
1 | export { default as BasicTable } from './src/BasicTable.vue'
2 | export { default as TableAction } from './src/components/TableAction.vue'
3 | export { default as EditTableHeaderIcon } from './src/components/EditTableHeaderIcon.vue'
4 | export { default as TableImg } from './src/components/TableImg.vue'
5 |
6 | export * from './src/types/table'
7 | export * from './src/types/pagination'
8 | export * from './src/types/tableAction'
9 | export { useTable } from './src/hooks/useTable'
10 | export type { FormSchema, FormProps } from '@/components/form/src/types/form'
11 | export type { EditRecordRow } from './src/components/editable'
12 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/componentMap.ts:
--------------------------------------------------------------------------------
1 | import type { Component } from 'vue'
2 | import {
3 | Input,
4 | Select,
5 | Checkbox,
6 | InputNumber,
7 | Switch,
8 | DatePicker,
9 | TimePicker,
10 | } from 'ant-design-vue'
11 | import type { ComponentType } from './types/componentType'
12 | import { ApiSelect, ApiTreeSelect } from '@/components/form'
13 |
14 | const componentMap = new Map()
15 |
16 | componentMap.set('Input', Input)
17 | componentMap.set('InputNumber', InputNumber)
18 | componentMap.set('Select', Select)
19 | componentMap.set('ApiSelect', ApiSelect)
20 | componentMap.set('ApiTreeSelect', ApiTreeSelect)
21 | componentMap.set('Switch', Switch)
22 | componentMap.set('Checkbox', Checkbox)
23 | componentMap.set('DatePicker', DatePicker)
24 | componentMap.set('TimePicker', TimePicker)
25 |
26 | export function add(compName: ComponentType, component: Component) {
27 | componentMap.set(compName, component)
28 | }
29 |
30 | export function del(compName: ComponentType) {
31 | componentMap.delete(compName)
32 | }
33 |
34 | export { componentMap }
35 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/components/EditTableHeaderIcon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ title }}
5 |
6 |
7 |
8 |
17 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/components/editable/CellComponent.ts:
--------------------------------------------------------------------------------
1 | import type { FunctionalComponent, defineComponent } from 'vue'
2 | import type { ComponentType } from '../../types/componentType'
3 | import { componentMap } from '@/components/table/src/componentMap'
4 |
5 | import { Popover } from 'ant-design-vue'
6 | import { h } from 'vue'
7 |
8 | export interface ComponentProps {
9 | component: ComponentType
10 | rule: boolean
11 | popoverVisible: boolean
12 | ruleMessage: string
13 | getPopupContainer?: AnyFunction
14 | }
15 |
16 | export const CellComponent: FunctionalComponent = (
17 | {
18 | component = 'Input',
19 | rule = true,
20 | ruleMessage,
21 | popoverVisible,
22 | getPopupContainer,
23 | }: ComponentProps,
24 | { attrs },
25 | ) => {
26 | const Comp = componentMap.get(component) as typeof defineComponent
27 |
28 | const DefaultComp = h(Comp, attrs)
29 | if (!rule) {
30 | return DefaultComp
31 | }
32 | return h(
33 | Popover,
34 | {
35 | overlayClassName: 'edit-cell-rule-popover',
36 | visible: !!popoverVisible,
37 | ...(getPopupContainer ? { getPopupContainer } : {}),
38 | },
39 | {
40 | default: () => DefaultComp,
41 | content: () => ruleMessage,
42 | },
43 | )
44 | }
45 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/components/editable/helper.ts:
--------------------------------------------------------------------------------
1 | import { ComponentType } from '../../types/componentType'
2 | import { useI18n } from '@pkg/locale'
3 |
4 | const { t } = useI18n()
5 |
6 | /**
7 | * @description: 生成placeholder
8 | */
9 | export function createPlaceholderMessage(component: ComponentType) {
10 | if (component.includes('Input')) {
11 | return t('common.inputText')
12 | }
13 | if (component.includes('Picker')) {
14 | return t('common.chooseText')
15 | }
16 |
17 | if (
18 | component.includes('Select') ||
19 | component.includes('Checkbox') ||
20 | component.includes('Radio') ||
21 | component.includes('Switch') ||
22 | component.includes('DatePicker') ||
23 | component.includes('TimePicker')
24 | ) {
25 | return t('common.chooseText')
26 | }
27 | return ''
28 | }
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/components/settings/FullScreenSetting.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ t('component.table.settingFullScreen') }}
5 |
6 |
7 |
8 |
9 |
10 |
42 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/components/settings/RedoSetting.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ t('common.redo') }}
5 |
6 |
7 |
8 |
9 |
34 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/const.ts:
--------------------------------------------------------------------------------
1 | import { componentSetting } from '@pkg/setting'
2 |
3 | const { table } = componentSetting
4 |
5 | const {
6 | pageSizeOptions,
7 | defaultPageSize,
8 | fetchSetting,
9 | defaultSize,
10 | defaultSortFn,
11 | defaultFilterFn,
12 | } = table
13 |
14 | export const ROW_KEY = 'key'
15 |
16 | // Optional display number per page;
17 | export const PAGE_SIZE_OPTIONS = pageSizeOptions
18 |
19 | // Number of items displayed per page
20 | export const PAGE_SIZE = defaultPageSize
21 |
22 | // Common interface field settings
23 | export const FETCH_SETTING = fetchSetting
24 |
25 | // Default Size
26 | export const DEFAULT_SIZE = defaultSize
27 |
28 | // Configure general sort function
29 | export const DEFAULT_SORT_FN = defaultSortFn
30 |
31 | export const DEFAULT_FILTER_FN = defaultFilterFn
32 |
33 | // Default layout of table cells
34 | export const DEFAULT_ALIGN = 'center'
35 |
36 | export const INDEX_COLUMN_FLAG = 'INDEX'
37 |
38 | export const ACTION_COLUMN_FLAG = 'ACTION'
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/hooks/useLoading.ts:
--------------------------------------------------------------------------------
1 | import { ref, ComputedRef, unref, computed, watch } from 'vue'
2 | import type { BasicTableProps } from '../types/table'
3 |
4 | export function useLoading(props: ComputedRef) {
5 | const loadingRef = ref(unref(props).loading)
6 |
7 | watch(
8 | () => unref(props).loading,
9 | (loading) => {
10 | loadingRef.value = loading
11 | },
12 | )
13 |
14 | const getLoading = computed(() => unref(loadingRef))
15 |
16 | function setLoading(loading: boolean) {
17 | loadingRef.value = loading
18 | }
19 |
20 | return { getLoading, setLoading }
21 | }
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/hooks/useTableContext.ts:
--------------------------------------------------------------------------------
1 | import type { Ref } from 'vue'
2 | import type { BasicTableProps, TableActionType } from '../types/table'
3 | import { provide, inject, ComputedRef } from 'vue'
4 |
5 | const key = Symbol('basic-table')
6 |
7 | type Instance = TableActionType & {
8 | wrapRef: Ref>
9 | getBindValues: ComputedRef
10 | }
11 |
12 | type RetInstance = Omit & {
13 | getBindValues: ComputedRef
14 | }
15 |
16 | export function createTableContext(instance: Instance) {
17 | provide(key, instance)
18 | }
19 |
20 | export function useTableContext(): RetInstance {
21 | return inject(key) as RetInstance
22 | }
23 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/hooks/useTableStyle.ts:
--------------------------------------------------------------------------------
1 | import type { ComputedRef } from 'vue'
2 | import type { BasicTableProps, TableCustomRecord } from '../types/table'
3 | import { unref } from 'vue'
4 | import { isFunction } from '@pkg/utils'
5 |
6 | export function useTableStyle(
7 | propsRef: ComputedRef,
8 | prefixCls: string,
9 | ) {
10 | function getRowClassName(record: TableCustomRecord, index: number) {
11 | const { striped, rowClassName } = unref(propsRef)
12 | const classNames: string[] = []
13 | if (striped) {
14 | classNames.push((index || 0) % 2 === 1 ? `${prefixCls}-row__striped` : '')
15 | }
16 | if (rowClassName && isFunction(rowClassName)) {
17 | classNames.push(rowClassName(record, index))
18 | }
19 | return classNames.filter((cls) => !!cls).join(' ')
20 | }
21 |
22 | return { getRowClassName }
23 | }
24 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/types/componentType.ts:
--------------------------------------------------------------------------------
1 | export type ComponentType =
2 | | 'Input'
3 | | 'InputNumber'
4 | | 'Select'
5 | | 'ApiSelect'
6 | | 'ApiTreeSelect'
7 | | 'Checkbox'
8 | | 'Switch'
9 | | 'DatePicker'
10 | | 'TimePicker'
11 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/components/table/src/types/tableAction.ts:
--------------------------------------------------------------------------------
1 | import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes'
2 | import { TooltipProps } from 'ant-design-vue/es/tooltip/Tooltip'
3 | import { RoleEnum } from '@pkg/tokens'
4 | export interface ActionItem extends ButtonProps {
5 | onClick?: AnyFunction
6 | label?: string
7 | color?: 'success' | 'error' | 'warning'
8 | icon?: string
9 | popConfirm?: PopConfirm
10 | disabled?: boolean
11 | divider?: boolean
12 | // 权限编码控制是否显示
13 | auth?: RoleEnum | RoleEnum[] | string | string[]
14 | // 业务控制是否显示
15 | ifShow?: boolean | ((action: ActionItem) => boolean)
16 | tooltip?: string | TooltipProps
17 | }
18 |
19 | export interface PopConfirm {
20 | title: string
21 | okText?: string
22 | cancelText?: string
23 | confirm: AnyFunction
24 | cancel?: AnyFunction
25 | icon?: string
26 | placement?:
27 | | 'top'
28 | | 'left'
29 | | 'right'
30 | | 'bottom'
31 | | 'topLeft'
32 | | 'topRight'
33 | | 'leftTop'
34 | | 'leftBottom'
35 | | 'rightTop'
36 | | 'rightBottom'
37 | | 'bottomLeft'
38 | | 'bottomRight'
39 | }
40 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/component/use-page-context.ts:
--------------------------------------------------------------------------------
1 | import type { InjectionKey, ComputedRef, Ref } from 'vue'
2 | import { createContext, useContext } from '@pkg/use'
3 |
4 | export interface PageContextProps {
5 | contentHeight: ComputedRef
6 | pageHeight: Ref
7 | setPageHeight: (height: number) => Promise
8 | }
9 |
10 | const key: InjectionKey = Symbol()
11 |
12 | export function createPageContext(context: PageContextProps) {
13 | return createContext(context, key, { native: true })
14 | }
15 |
16 | export function usePageContext() {
17 | return useContext(key)
18 | }
19 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/setting/useMultipleTabSetting.ts:
--------------------------------------------------------------------------------
1 | import type { MultiTabsSetting } from '@pkg/types'
2 |
3 | import { computed } from 'vue'
4 |
5 | import { useAppStore } from '@/store/app'
6 |
7 | export function useMultipleTabSetting() {
8 | const appStore = useAppStore()
9 |
10 | const getShowMultipleTab = computed(() => appStore.getMultiTabsSetting.show)
11 |
12 | const getShowQuick = computed(() => appStore.getMultiTabsSetting.showQuick)
13 |
14 | const getShowRedo = computed(() => appStore.getMultiTabsSetting.showRedo)
15 |
16 | const getShowFold = computed(() => appStore.getMultiTabsSetting.showFold)
17 |
18 | function setMultipleTabSetting(multiTabsSetting: Partial) {
19 | appStore.setProjectConfig({ multiTabsSetting })
20 | }
21 | return {
22 | setMultipleTabSetting,
23 | getShowMultipleTab,
24 | getShowQuick,
25 | getShowRedo,
26 | getShowFold,
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/use-app-inject.ts:
--------------------------------------------------------------------------------
1 | import { useAppProviderContext } from '@/components/application'
2 | import { computed, unref } from 'vue'
3 |
4 | export function useAppInject() {
5 | const values = useAppProviderContext()
6 |
7 | return {
8 | getIsMobile: computed(() => unref(values.isMobile)),
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/use-echarts/echarts.ts:
--------------------------------------------------------------------------------
1 | import * as echarts from 'echarts/core'
2 | import { SVGRenderer } from 'echarts/renderers'
3 | import {
4 | BarChart,
5 | LineChart,
6 | PieChart,
7 | MapChart,
8 | PictorialBarChart,
9 | RadarChart,
10 | } from 'echarts/charts'
11 | import {
12 | TitleComponent,
13 | TooltipComponent,
14 | GridComponent,
15 | PolarComponent,
16 | AriaComponent,
17 | ParallelComponent,
18 | LegendComponent,
19 | RadarComponent,
20 | ToolboxComponent,
21 | DataZoomComponent,
22 | VisualMapComponent,
23 | TimelineComponent,
24 | CalendarComponent,
25 | GraphicComponent,
26 | } from 'echarts/components'
27 |
28 | echarts.use([
29 | LegendComponent,
30 | TitleComponent,
31 | TooltipComponent,
32 | GridComponent,
33 | PolarComponent,
34 | AriaComponent,
35 | ParallelComponent,
36 | BarChart,
37 | LineChart,
38 | PieChart,
39 | MapChart,
40 | RadarChart,
41 | SVGRenderer,
42 | PictorialBarChart,
43 | RadarComponent,
44 | ToolboxComponent,
45 | DataZoomComponent,
46 | VisualMapComponent,
47 | TimelineComponent,
48 | CalendarComponent,
49 | GraphicComponent,
50 | ])
51 |
52 | export default echarts
53 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/useContextMenu.ts:
--------------------------------------------------------------------------------
1 | import { onUnmounted, getCurrentInstance } from 'vue'
2 | import {
3 | createContextMenu,
4 | destroyContextMenu,
5 | } from '@/components/context-menu'
6 | import type { ContextMenuItem } from '@/components/context-menu'
7 | export type { ContextMenuItem }
8 | export function useContextMenu(authRemove = true) {
9 | if (getCurrentInstance() && authRemove) {
10 | onUnmounted(() => {
11 | destroyContextMenu()
12 | })
13 | }
14 | return [createContextMenu, destroyContextMenu]
15 | }
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/useDesign.ts:
--------------------------------------------------------------------------------
1 | import { useAppProviderContext } from '@/components/application'
2 | export function useDesign(scope: string) {
3 | const values = useAppProviderContext()
4 | // const $style = cssModule ? useCssModule() : {};
5 |
6 | // const style: Record = {};
7 | // if (cssModule) {
8 | // Object.keys($style).forEach((key) => {
9 | // // const moduleCls = $style[key];
10 | // const k = key.replace(new RegExp(`^${values.prefixCls}-?`, 'ig'), '');
11 | // style[lowerFirst(k)] = $style[key];
12 | // });
13 | // }
14 | return {
15 | // prefixCls: computed(() => `${values.prefixCls}-${scope}`),
16 | prefixCls: `${values.prefixCls}-${scope}`,
17 | prefixVar: values.prefixCls,
18 | // style,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/useFullContent.ts:
--------------------------------------------------------------------------------
1 | import { computed, unref } from 'vue'
2 |
3 | import { useAppStore } from '@/store/app'
4 |
5 | import { useRouter } from 'vue-router'
6 |
7 | /**
8 | * @description: Full screen display content
9 | */
10 | export const useFullContent = () => {
11 | const appStore = useAppStore()
12 | const router = useRouter()
13 | const { currentRoute } = router
14 |
15 | // Whether to display the content in full screen without displaying the menu
16 | const getFullContent = computed(() => {
17 | // Query parameters, the full screen is displayed when the address bar has a full parameter
18 | const route = unref(currentRoute)
19 | const query = route.query
20 | if (query && Reflect.has(query, '__full__')) {
21 | return true
22 | }
23 | // Return to the configuration in the configuration file
24 | return appStore.getProjectConfig.fullContent
25 | })
26 |
27 | return { getFullContent }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/hooks/web/useSortable.ts:
--------------------------------------------------------------------------------
1 | import type { Ref } from 'vue'
2 | import type { Options } from 'sortablejs'
3 |
4 | import { nextTick, unref } from 'vue'
5 |
6 | export function useSortable(
7 | el: HTMLElement | Ref,
8 | options?: Options,
9 | ) {
10 | function initSortable() {
11 | nextTick(async () => {
12 | if (!el) return
13 |
14 | const Sortable = (await import('sortablejs')).default
15 | Sortable.create(unref(el), {
16 | animation: 500,
17 | delay: 400,
18 | delayOnTouchOnly: true,
19 | ...options,
20 | })
21 | })
22 | }
23 |
24 | return { initSortable }
25 | }
26 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/internal/factory/component-factory.ts:
--------------------------------------------------------------------------------
1 | import { defineAsyncComponent, h } from 'vue'
2 | import { Spin } from 'ant-design-vue'
3 | import { NOOP } from '@pkg/utils'
4 |
5 | interface Options {
6 | size?: 'default' | 'small' | 'large'
7 | delay?: number
8 | timeout?: number
9 | loading?: boolean
10 | retry?: boolean
11 | }
12 |
13 | export const createAsyncComponent = (
14 | loader: AnyFunction,
15 | options: Options = {},
16 | ) => {
17 | const {
18 | size = 'small',
19 | delay = 100,
20 | timeout = 30000,
21 | loading = false,
22 | retry = true,
23 | } = options
24 | return defineAsyncComponent({
25 | loader,
26 | loadingComponent: loading ? h(Spin, { spinning: true, size }) : undefined,
27 | timeout,
28 | delay,
29 | onError: !retry
30 | ? NOOP
31 | : (error, retry, fail, attempts) => {
32 | if (error.message.match(/fetch/) && attempts <= 3) {
33 | retry()
34 | } else {
35 | fail()
36 | }
37 | },
38 | })
39 | }
40 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/internal/factory/index.ts:
--------------------------------------------------------------------------------
1 | export { createAsyncComponent } from './component-factory'
2 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/internal/index.ts:
--------------------------------------------------------------------------------
1 | export * from './config'
2 | export * from './pinia'
3 | export * from './factory'
4 | export * from './component'
5 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/internal/pinia/index.ts:
--------------------------------------------------------------------------------
1 | import { createPinia } from 'pinia'
2 | import { createPersistPlugin } from './persist'
3 | import { createStorageName } from '@/internal/config'
4 |
5 | const pinia = createPinia()
6 |
7 | // Persistence plugin, modified from open source, adding namespace support
8 | pinia.use(createPersistPlugin({ namespace: createStorageName() }))
9 |
10 | export { pinia }
11 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/content/useContentContext.ts:
--------------------------------------------------------------------------------
1 | import type { InjectionKey, ComputedRef } from 'vue'
2 | import { createContext, useContext } from '@pkg/use'
3 |
4 | export interface ContentContextProps {
5 | contentHeight: ComputedRef
6 | setPageHeight: (height: number) => Promise
7 | }
8 |
9 | const key: InjectionKey = Symbol()
10 |
11 | export function createContentContext(context: ContentContextProps) {
12 | return createContext(context, key, { native: true })
13 | }
14 |
15 | export function useContentContext() {
16 | return useContext(key)
17 | }
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/header/components/FullScreen.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
41 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/header/components/index.ts:
--------------------------------------------------------------------------------
1 | import { createAsyncComponent } from '@/internal'
2 | import FullScreen from './FullScreen.vue'
3 | import UserDropDown from './user-dropdown/index.vue'
4 |
5 | export const LayoutBreadcrumb = createAsyncComponent(
6 | () => import('./Breadcrumb.vue'),
7 | )
8 |
9 | export const Notify = createAsyncComponent(() => import('./notify/index.vue'))
10 |
11 | export { FullScreen, UserDropDown }
12 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/header/components/user-dropdown/DropMenuItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
30 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/setting/components/index.ts:
--------------------------------------------------------------------------------
1 | import { createAsyncComponent } from '@/internal'
2 |
3 | export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue'))
4 | export const ThemeColorPicker = createAsyncComponent(
5 | () => import('./ThemeColorPicker.vue'),
6 | )
7 | export const SettingFooter = createAsyncComponent(
8 | () => import('./SettingFooter.vue'),
9 | )
10 | export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue'))
11 | export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue'))
12 | export const InputNumberItem = createAsyncComponent(
13 | () => import('./InputNumberItem.vue'),
14 | )
15 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/setting/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
27 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/tabs/components/TabRedo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
34 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/tabs/types.ts:
--------------------------------------------------------------------------------
1 | import type { DropMenu } from '@/components/dropdown/index'
2 | import type { RouteLocationNormalized } from 'vue-router'
3 |
4 | export enum TabContentEnum {
5 | TAB_TYPE,
6 | EXTRA_TYPE,
7 | }
8 |
9 | export type { DropMenu }
10 |
11 | export interface TabContentProps {
12 | tabItem: RouteLocationNormalized
13 | type?: TabContentEnum
14 | trigger?: ('click' | 'hover' | 'contextmenu')[]
15 | }
16 |
17 | export enum MenuEventEnum {
18 | REFRESH_PAGE,
19 | CLOSE_CURRENT,
20 | CLOSE_LEFT,
21 | CLOSE_RIGHT,
22 | CLOSE_OTHER,
23 | CLOSE_ALL,
24 | SCALE,
25 | }
26 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/trigger/HeaderTrigger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/trigger/SiderTrigger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/default/trigger/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/layouts/iframe/index.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/mitt/route-change.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Used to monitor routing changes to change the status of menus and tabs. There is no need to monitor the route, because the route status change is affected by the page rendering time, which will be slow
3 | */
4 | import type { RouteLocationNormalized } from 'vue-router'
5 |
6 | import { mitt, getRawRoute } from '@pkg/utils'
7 |
8 | const emitter = mitt()
9 |
10 | const key = Symbol()
11 |
12 | let lastChangeTab: RouteLocationNormalized
13 |
14 | export function setRouteChange(lastChangeRoute: RouteLocationNormalized) {
15 | const _router = getRawRoute(lastChangeRoute)
16 | emitter.emit(key, _router)
17 | lastChangeTab = _router
18 | }
19 |
20 | export function listenerRouteChange(
21 | callback: (route: RouteLocationNormalized) => void,
22 | immediate = true,
23 | ) {
24 | emitter.on(key, callback)
25 | immediate && lastChangeTab && callback(lastChangeTab)
26 | }
27 |
28 | export function removeTabChangeListener() {
29 | emitter.clear()
30 | }
31 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/theme/dark.ts:
--------------------------------------------------------------------------------
1 | import { darkCssIsReady, loadDarkThemeCss } from 'vite-plugin-theme/es/client'
2 | import { addClass, hasClass, removeClass } from '@pkg/utils'
3 |
4 | export async function updateDarkTheme(mode: string | null = 'light') {
5 | const htmlRoot = document.getElementById('htmlRoot')
6 | if (!htmlRoot) {
7 | return
8 | }
9 | const hasDarkClass = hasClass(htmlRoot, 'dark')
10 | if (mode === 'dark') {
11 | if (import.meta.env.PROD && !darkCssIsReady) {
12 | await loadDarkThemeCss()
13 | }
14 | htmlRoot.setAttribute('data-theme', 'dark')
15 | if (!hasDarkClass) {
16 | addClass(htmlRoot, 'dark')
17 | }
18 | } else {
19 | htmlRoot.setAttribute('data-theme', 'light')
20 | if (hasDarkClass) {
21 | removeClass(htmlRoot, 'dark')
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/theme/index.ts:
--------------------------------------------------------------------------------
1 | import { getThemeColors, generateColors } from './theme'
2 |
3 | import { replaceStyleVariables } from 'vite-plugin-theme/es/client'
4 | import {
5 | mixLighten,
6 | mixDarken,
7 | tinycolor,
8 | } from 'vite-plugin-theme/es/colorUtils'
9 |
10 | export async function changeTheme(color: string) {
11 | const colors = generateColors({
12 | mixDarken,
13 | mixLighten,
14 | tinycolor,
15 | color,
16 | })
17 |
18 | return await replaceStyleVariables({
19 | colorVariables: [...getThemeColors(color), ...colors],
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/theme/update-color-weak.ts:
--------------------------------------------------------------------------------
1 | import { toggleClass } from './util'
2 |
3 | /**
4 | * Change the status of the project's color weakness mode
5 | * @param colorWeak
6 | */
7 | export function updateColorWeak(colorWeak: boolean) {
8 | toggleClass(colorWeak, 'color-weak', document.documentElement)
9 | }
10 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/theme/update-gray-mode.ts:
--------------------------------------------------------------------------------
1 | import { toggleClass } from './util'
2 |
3 | /**
4 | * Change project gray mode status
5 | * @param gray
6 | */
7 | export function updateGrayMode(gray: boolean) {
8 | toggleClass(gray, 'gray-mode', document.documentElement)
9 | }
10 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/logics/theme/util.ts:
--------------------------------------------------------------------------------
1 | const docEle = document.documentElement
2 | export function toggleClass(
3 | flag: boolean,
4 | clsName: string,
5 | target?: HTMLElement,
6 | ) {
7 | const targetEl = target || document.body
8 | let { className } = targetEl
9 | className = className.replace(clsName, '')
10 | targetEl.className = flag ? `${className} ${clsName} ` : className
11 | }
12 |
13 | export function setCssVar(prop: string, val: any, dom = docEle) {
14 | dom.style.setProperty(prop, val)
15 | }
16 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/constant.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @description: default layout
3 | */
4 | export const LAYOUT = () => import('@/layouts/default/index.vue')
5 |
6 | /**
7 | * @description: parent-layout
8 | */
9 | export const getParentLayout = () => () =>
10 | new Promise((resolve) => {
11 | resolve({ name: 'ParentLayout' })
12 | })
13 |
14 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/guard/state.ts:
--------------------------------------------------------------------------------
1 | import type { Router } from 'vue-router'
2 | import { useAppStore } from '@/store/app'
3 | import { useMultipleTabStore } from '@/store/multiple-tab'
4 | import { useUserStore } from '@/store/user'
5 | import { usePermissionStore } from '@/store/permission'
6 | import { PageEnum } from '@pkg/tokens'
7 | import { removeTabChangeListener } from '@/logics/mitt/route-change'
8 |
9 | export function createStateGuard(router: Router) {
10 | router.afterEach((to) => {
11 | // Just enter the login page and clear the authentication information
12 | if (to.path === PageEnum.BASE_LOGIN) {
13 | const tabStore = useMultipleTabStore()
14 | const userStore = useUserStore()
15 | const appStore = useAppStore()
16 | const permissionStore = usePermissionStore()
17 | appStore.resetAllState()
18 | permissionStore.resetState()
19 | tabStore.resetState()
20 | userStore.resetState()
21 | removeTabChangeListener()
22 | }
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/index.ts:
--------------------------------------------------------------------------------
1 | import type { App } from 'vue'
2 | import { createRouter, createWebHistory } from 'vue-router'
3 | import { basicRoutes } from './routes'
4 |
5 | // 白名单应该包含基本静态路由
6 | const WHITE_NAME_LIST: string[] = []
7 |
8 | ;(() => {
9 | const getRouteNames = (array: any[]) =>
10 | array.forEach((item) => {
11 | WHITE_NAME_LIST.push(item.name)
12 | getRouteNames(item.children || [])
13 | })
14 |
15 | getRouteNames(basicRoutes)
16 | })()
17 |
18 | // app router
19 | export const router = createRouter({
20 | history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
21 | routes: basicRoutes,
22 | strict: true,
23 | scrollBehavior: () => ({ left: 0, top: 0 }),
24 | })
25 |
26 | // reset router
27 | export const resetRouter = () => {
28 | router.getRoutes().forEach((route) => {
29 | const { name } = route
30 | if (name && !WHITE_NAME_LIST.includes(name as string)) {
31 | router.hasRoute(name) && router.removeRoute(name)
32 | }
33 | })
34 | }
35 |
36 | // config router
37 | export const setupRouter = (app: App) => app.use(router)
38 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/routes/mainOut.ts:
--------------------------------------------------------------------------------
1 | /**
2 | The routing of this file will not show the layout.
3 | It is an independent new page.
4 | the contents of the file still need to log in to access
5 | Test with annotations turned on
6 |
7 | 这个文件的路由不会显示布局。
8 | 这是一个独立的新页面。
9 | 文件内容仍需登录才能访问
10 | 打开注释后进行测试
11 | */
12 |
13 | // test
14 | // http:ip:port/main-out
15 | export const mainOutRoutes: RouteRecordItem[] = [
16 | // {
17 | // path: '/main-out',
18 | // name: 'MainOut',
19 | // component: () => import('@/views/demo/main-out/index.vue'),
20 | // meta: {
21 | // title: 'MainOut',
22 | // ignoreAuth: true,
23 | // },
24 | // },
25 | ]
26 |
27 | export const mainOutRouteNames = mainOutRoutes.map((item) => item.name)
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/routes/modules/about.ts:
--------------------------------------------------------------------------------
1 | import { LAYOUT } from '@/router/constant'
2 | import { t } from '@pkg/locale'
3 |
4 | const dashboard: RouteRecordItem = {
5 | path: '/about',
6 | name: 'About',
7 | component: LAYOUT,
8 | redirect: '/about/index',
9 | meta: {
10 | hideChildrenInMenu: true,
11 | icon: 'simple-icons:about-dot-me',
12 | title: t('routes.dashboard.about'),
13 | orderNo: 100000,
14 | },
15 | children: [
16 | {
17 | path: 'index',
18 | name: 'AboutPage',
19 | component: () => import('@/views/sys/about/index.vue'),
20 | meta: {
21 | title: t('routes.dashboard.about'),
22 | icon: 'simple-icons:about-dot-me',
23 | hideMenu: true,
24 | },
25 | },
26 | ],
27 | }
28 |
29 | export default dashboard
30 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/routes/modules/crm/index.ts:
--------------------------------------------------------------------------------
1 | import { LAYOUT } from '@/router/constant'
2 | import { t } from '@pkg/locale'
3 |
4 | const crm: RouteRecordItem = {
5 | path: '/crm',
6 | name: 'crm',
7 | component: LAYOUT,
8 | redirect: '/crm/customer',
9 | meta: {
10 | orderNo: 2001,
11 | icon: 'carbon:development',
12 | title: t('routes.crm.crm'),
13 | },
14 | children: [
15 | {
16 | path: 'customer',
17 | name: 'customer',
18 | component: () => import('@/views/CRM/Customer/index.vue'),
19 | meta: {
20 | // affix: true,
21 | title: t('routes.crm.customer'),
22 | },
23 | },
24 | ],
25 | }
26 |
27 | export default crm
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/routes/modules/dashboard.ts:
--------------------------------------------------------------------------------
1 | import { LAYOUT } from '@/router/constant'
2 | import { t } from '@pkg/locale'
3 |
4 | const dashboard: RouteRecordItem = {
5 | path: '/dashboard',
6 | name: 'Dashboard',
7 | component: LAYOUT,
8 | redirect: '/dashboard/analysis',
9 | meta: {
10 | orderNo: 10,
11 | icon: 'ion:grid-outline',
12 | title: t('routes.dashboard.dashboard'),
13 | },
14 | children: [
15 | {
16 | path: 'analysis',
17 | name: 'Analysis',
18 | component: () => import('@/views/dashboard/analysis/index.vue'),
19 | meta: {
20 | // affix: true,
21 | title: t('routes.dashboard.analysis'),
22 | },
23 | },
24 | {
25 | path: 'workbench',
26 | name: 'Workbench',
27 | component: () => import('@/views/dashboard/workbench/index.vue'),
28 | meta: {
29 | title: t('routes.dashboard.workbench'),
30 | },
31 | },
32 | ],
33 | }
34 |
35 | export default dashboard
36 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/router/types.ts:
--------------------------------------------------------------------------------
1 | import type { RouteMeta } from 'vue-router'
2 | import { RoleEnum } from '@pkg/tokens'
3 |
4 | export interface MenuTag {
5 | type?: 'primary' | 'error' | 'warn' | 'success'
6 | content?: string
7 | dot?: boolean
8 | }
9 |
10 | export interface Menu {
11 | name: string
12 |
13 | icon?: string
14 |
15 | path: string
16 |
17 | // path contains param, auto assignment.
18 | paramPath?: string
19 |
20 | disabled?: boolean
21 |
22 | children?: Menu[]
23 |
24 | orderNo?: number
25 |
26 | roles?: RoleEnum[]
27 |
28 | meta?: Partial
29 |
30 | tag?: MenuTag
31 |
32 | hideMenu?: boolean
33 | }
34 |
35 | export interface MenuModule {
36 | orderNo?: number
37 | menu: Menu
38 | }
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/ant/amis_override.less:
--------------------------------------------------------------------------------
1 | @import './pagination.less';
2 |
3 | .ant-message {
4 | z-index: 10000000 !important;
5 | }
6 |
7 | .ant-message .anticon {
8 | top: -5px !important;
9 | }
10 |
11 | .anticon .anticon-bell {
12 | position: relative !important;
13 | top: -5px !important;
14 | }
15 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/ant/index.less:
--------------------------------------------------------------------------------
1 | @import './pagination.less';
2 | @import './amis_override.less';
3 |
4 | .modal-icon-warning {
5 | color: @warning-color !important;
6 | }
7 |
8 | .modal-icon-success {
9 | color: @success-color !important;
10 | }
11 |
12 | .modal-icon-error {
13 | color: @error-color !important;
14 | }
15 |
16 | .modal-icon-info {
17 | color: @primary-color !important;
18 | }
19 |
20 | .ant-checkbox-checked .ant-checkbox-inner::after,
21 | .ant-tree-checkbox-checked .ant-tree-checkbox-inner::after {
22 | border-top: 0 !important;
23 | border-left: 0 !important;
24 | }
25 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/config.less:
--------------------------------------------------------------------------------
1 | @import (reference) 'color.less';
2 | @import (reference) 'var/index.less';
3 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/index.less:
--------------------------------------------------------------------------------
1 | @import 'transition.less';
2 | @import 'var/index.less';
3 | @import 'public.less';
4 | @import 'ant/index.less';
5 | @import './theme.less';
6 |
7 | input:-webkit-autofill {
8 | box-shadow: 0 0 0 1000px white inset !important;
9 | }
10 |
11 | :-webkit-autofill {
12 | transition: background-color 5000s ease-in-out 0s !important;
13 | }
14 |
15 | html {
16 | overflow: hidden;
17 | text-size-adjust: 100%;
18 | }
19 |
20 | html,
21 | body {
22 | width: 100%;
23 | height: 100%;
24 | overflow: visible !important;
25 | overflow-x: hidden !important;
26 |
27 | &.color-weak {
28 | filter: invert(80%);
29 | }
30 |
31 | &.gray-mode {
32 | filter: grayscale(100%);
33 | filter: progid:dximagetransform.microsoft.basicimage(grayscale=1);
34 | }
35 | }
36 |
37 | a:focus,
38 | a:active,
39 | button,
40 | div,
41 | svg,
42 | span {
43 | outline: none !important;
44 | }
45 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/index.ts:
--------------------------------------------------------------------------------
1 | import './index.less'
2 | import './tailwind.css'
3 | import 'ant-design-vue/dist/antd.less'
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/public.less:
--------------------------------------------------------------------------------
1 | #app {
2 | width: 100%;
3 | height: 100%;
4 | }
5 |
6 | ::-webkit-scrollbar {
7 | width: 7px;
8 | height: 8px;
9 | }
10 |
11 | ::-webkit-scrollbar-track {
12 | background-color: rgb(0 0 0 / 5%);
13 | }
14 |
15 | ::-webkit-scrollbar-thumb {
16 | background-color: rgb(144 147 153 / 30%);
17 | border-radius: 2px;
18 | box-shadow: inset 0 0 6px rgb(0 0 0 / 20%);
19 | }
20 |
21 | ::-webkit-scrollbar-thumb:hover {
22 | background-color: @border-color-dark;
23 | }
24 |
25 | // =================================
26 | // ==============nprogress==========
27 | // =================================
28 | #nprogress {
29 | pointer-events: none;
30 |
31 | .bar {
32 | position: fixed;
33 | top: 0;
34 | left: 0;
35 | z-index: 99999;
36 | width: 100%;
37 | height: 2px;
38 | background-color: @primary-color;
39 | opacity: 0.75;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/transition.less:
--------------------------------------------------------------------------------
1 | .transition-default() {
2 | &-enter-active,
3 | &-leave-active {
4 | transition: 0.3s cubic-bezier(0.25, 0.8, 0.5, 1) !important;
5 | }
6 |
7 | &-move {
8 | transition: transform 0.4s;
9 | }
10 | }
11 |
12 | /* fade-slide */
13 | .fade-slide-leave-active,
14 | .fade-slide-enter-active {
15 | transition: all 0.3s;
16 | }
17 |
18 | .fade-slide-enter-from {
19 | opacity: 0;
20 | transform: translateX(-30px);
21 | }
22 |
23 | .fade-slide-leave-to {
24 | opacity: 0;
25 | transform: translateX(30px);
26 | }
27 |
28 | .expand-transition {
29 | .transition-default();
30 | }
31 |
32 | .expand-x-transition {
33 | .transition-default();
34 | }
35 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/var/breakpoint.less:
--------------------------------------------------------------------------------
1 | // =================================
2 | // ==============屏幕断点============
3 | // =================================
4 |
5 | // Extra small screen / phone
6 | @screen-xs: 480px;
7 | @screen-xs-min: @screen-xs;
8 |
9 | // Small screen / tablet
10 | @screen-sm: 576px;
11 | @screen-sm-min: @screen-sm;
12 |
13 | // Medium screen / desktop
14 | @screen-md: 768px;
15 | @screen-md-min: @screen-md;
16 |
17 | // Large screen / wide desktop
18 | @screen-lg: 992px;
19 | @screen-lg-min: @screen-lg;
20 |
21 | // Extra large screen / full hd
22 | @screen-xl: 1200px;
23 | @screen-xl-min: @screen-xl;
24 |
25 | // Extra extra large screen / large desktop
26 | @screen-2xl: 1600px;
27 | @screen-2xl-min: @screen-2xl;
28 |
29 | @screen-xs-max: (@screen-sm-min - 1px);
30 | @screen-sm-max: (@screen-md-min - 1px);
31 | @screen-md-max: (@screen-lg-min - 1px);
32 | @screen-lg-max: (@screen-xl-min - 1px);
33 | @screen-xl-max: (@screen-2xl-min - 1px);
34 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/var/easing.less:
--------------------------------------------------------------------------------
1 | // =================================
2 | // ==============动画函数-===========
3 | // =================================
4 |
5 | @ease-base-out: cubic-bezier(0.7, 0.3, 0.1, 1);
6 | @ease-base-in: cubic-bezier(0.9, 0, 0.3, 0.7);
7 | @ease-out: cubic-bezier(0.215, 0.61, 0.355, 1);
8 | @ease-in: cubic-bezier(0.55, 0.055, 0.675, 0.19);
9 | @ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1);
10 | @ease-out-back: cubic-bezier(0.12, 0.4, 0.29, 1.46);
11 | @ease-in-back: cubic-bezier(0.71, -0.46, 0.88, 0.6);
12 | @ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46);
13 | @ease-out-circ: cubic-bezier(0.08, 0.82, 0.17, 1);
14 | @ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.34);
15 | @ease-in-out-circ: cubic-bezier(0.78, 0.14, 0.15, 0.86);
16 | @ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
17 | @ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
18 | @ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
19 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/styles/var/index.less:
--------------------------------------------------------------------------------
1 | @import (reference) '../color.less';
2 | @import 'easing';
3 | @import 'breakpoint';
4 |
5 | @namespace: vben;
6 |
7 | // tabs
8 | @multiple-height: 30px;
9 |
10 | // headers
11 | @header-height: 48px;
12 |
13 | // logo width
14 | @logo-width: 32px;
15 |
16 | @side-drag-z-index: 200;
17 |
18 | @page-loading-z-index: 10000;
19 |
20 | @lock-page-z-index: 3000;
21 |
22 | @layout-header-fixed-z-index: 500;
23 |
24 | @multiple-tab-fixed-z-index: 505;
25 |
26 | @layout-sider-fixed-z-index: 510;
27 |
28 | @layout-mix-sider-fixed-z-index: 550;
29 |
30 | @preview-comp-z-index: 1000;
31 |
32 | @page-footer-z-index: 99;
33 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/DynamicPage/EditModal.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
35 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/amis/schematpls/formItem_contentPicker.json:
--------------------------------------------------------------------------------
1 | {
2 | "label": "内容项选择下拉菜单",
3 | "name": "select",
4 | "type": "select",
5 | "checkAll": false,
6 | "searchable": true,
7 | "autoComplete": {
8 | "method": "post",
9 | "url": "/api/graphql",
10 | "data": null,
11 | "dataType": "json",
12 | "requestAdaptor": "const query=`{\r\n options:customer(status: PUBLISHED, first: 10,\r\n where: {displayText_contains: \"${api.body.term}\"}) {\r\n label:displayText\r\n value:contentItemId\r\n }\r\n}`\r\napi.data={query}\r\n\r\nreturn api\r\n",
13 | "adaptor": "",
14 | "replaceData": false
15 | }
16 | }
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/analysis/components/SiteAnalysis.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
39 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/analysis/components/props.ts:
--------------------------------------------------------------------------------
1 | import { PropType } from 'vue'
2 |
3 | export interface BasicProps {
4 | width: string
5 | height: string
6 | }
7 | export const basicProps = {
8 | width: {
9 | type: String as PropType,
10 | default: '100%',
11 | },
12 | height: {
13 | type: String as PropType,
14 | default: '280px',
15 | },
16 | }
17 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/analysis/data.ts:
--------------------------------------------------------------------------------
1 | export interface GrowCardItem {
2 | icon: string
3 | title: string
4 | value: number
5 | total: number
6 | color: string
7 | action: string
8 | }
9 |
10 | export const growCardList: GrowCardItem[] = [
11 | {
12 | title: '访问数',
13 | icon: 'visit-count',
14 | value: 2000,
15 | total: 120000,
16 | color: 'green',
17 | action: '月',
18 | },
19 | {
20 | title: '成交额',
21 | icon: 'total-sales',
22 | value: 20000,
23 | total: 500000,
24 | color: 'blue',
25 | action: '月',
26 | },
27 | {
28 | title: '下载数',
29 | icon: 'download-count',
30 | value: 8000,
31 | total: 120000,
32 | color: 'orange',
33 | action: '周',
34 | },
35 | {
36 | title: '成交数',
37 | icon: 'transaction',
38 | value: 5000,
39 | total: 50000,
40 | color: 'purple',
41 | action: '年',
42 | },
43 | ]
44 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/analysis/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
29 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/workbench/components/DynamicInfo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 更多
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{ item.date }}
12 |
13 |
14 |
15 | {{ item.name }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/workbench/components/ProjectCard.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 更多
5 |
6 |
7 |
8 |
9 |
10 | {{ item.title }}
11 |
12 | {{ item.desc }}
13 |
14 | {{ item.group }}
15 | {{ item.date }}
16 |
17 |
18 |
19 |
20 |
33 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/dashboard/workbench/components/QuickNav.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{ item.title }}
7 |
8 |
9 |
10 |
11 |
18 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/develop/contentType/dynamicIndex.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
32 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/iframe/FrameBlank.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/lock/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
14 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/login/login-form-title.vue:
--------------------------------------------------------------------------------
1 |
21 |
22 |
25 | {{ getFormTitle }}
26 |
27 |
28 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/login/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/login/loginCallback.vue:
--------------------------------------------------------------------------------
1 |
2 | 正在登陆...
3 |
4 |
5 |
20 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/login/logoutcallback.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 正在退出...
4 |
5 |
6 |
21 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/login/qrcode-form.vue:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
{{ t('sys.login.scanSign') }}
27 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/sys/redirect/index.vue:
--------------------------------------------------------------------------------
1 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/system/account/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
32 |
--------------------------------------------------------------------------------
/apps/ant-admin/src/views/system/password/pwd.data.ts:
--------------------------------------------------------------------------------
1 | import { FormSchema } from '@/components/form'
2 |
3 | export const formSchema: FormSchema[] = [
4 | {
5 | field: 'passwordOld',
6 | label: '当前密码',
7 | component: 'InputPassword',
8 | required: true,
9 | },
10 | {
11 | field: 'passwordNew',
12 | label: '新密码',
13 | component: 'InputPassword',
14 | componentProps: {
15 | placeholder: '新密码',
16 | },
17 | rules: [
18 | {
19 | required: true,
20 | message: '请输入新密码',
21 | },
22 | ],
23 | },
24 | {
25 | field: 'confirmPassword',
26 | label: '确认密码',
27 | component: 'InputPassword',
28 |
29 | dynamicRules: ({ values }) => {
30 | return [
31 | {
32 | required: true,
33 | validator: (_, value) => {
34 | if (!value) {
35 | return Promise.reject('不能为空')
36 | }
37 | if (value !== values.passwordNew) {
38 | return Promise.reject('两次输入的密码不一致!')
39 | }
40 | return Promise.resolve()
41 | },
42 | },
43 | ]
44 | },
45 | },
46 | ]
47 |
--------------------------------------------------------------------------------
/apps/ant-admin/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = require('@config/css-preprocess/tailwind')
2 |
--------------------------------------------------------------------------------
/apps/ant-admin/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig/base.json",
3 | "compilerOptions": {
4 | "target": "esnext",
5 | "module": "esnext",
6 | "baseUrl": ".",
7 | "paths": {
8 | "@/*": ["src/*"]
9 | },
10 | "lib": ["dom", "esnext"],
11 | "types": ["vite/client"]
12 | },
13 | "include": ["src", "mock", "vite.config.ts"]
14 | }
15 |
--------------------------------------------------------------------------------
/apps/ant-admin/vite.config.ts:
--------------------------------------------------------------------------------
1 | import type { ViteConfig } from '@config/vite'
2 | import { createViteConfig } from '@config/vite'
3 |
4 | export default createViteConfig(process.cwd(), 'ant') as ViteConfig
5 |
--------------------------------------------------------------------------------
/configs/css-preprocess/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@config/css-preprocess",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "postcss.js",
7 | "tailwind.js"
8 | ],
9 | "scripts": {
10 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
11 | },
12 | "dependencies": {
13 | "autoprefixer": "^10.4.4",
14 | "postcss": "^8.4.12",
15 | "tailwindcss": "^3.0.23"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/configs/css-preprocess/postcss.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/configs/lint/commitlint.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | rules: {
4 | 'body-leading-blank': [2, 'always'],
5 | 'footer-leading-blank': [1, 'always'],
6 | 'header-max-length': [2, 'always', 108],
7 | 'subject-empty': [2, 'never'],
8 | 'type-empty': [2, 'never'],
9 | 'subject-case': [0],
10 | 'type-enum': [
11 | 2,
12 | 'always',
13 | [
14 | 'feat',
15 | 'fix',
16 | 'perf',
17 | 'style',
18 | 'docs',
19 | 'test',
20 | 'refactor',
21 | 'build',
22 | 'ci',
23 | 'chore',
24 | 'revert',
25 | 'workflow',
26 | 'types',
27 | 'wip',
28 | ],
29 | ],
30 | },
31 | }
32 |
--------------------------------------------------------------------------------
/configs/lint/lintstaged.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
3 | '*.vue': ['eslint --fix', 'stylelint --fix', 'prettier --write'],
4 | '*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
5 | }
6 |
--------------------------------------------------------------------------------
/configs/lint/prettier.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 80,
3 | semi: false,
4 | singleQuote: true,
5 | trailingComma: 'all',
6 | endOfLine: 'auto',
7 | }
8 |
--------------------------------------------------------------------------------
/configs/tsconfig/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Base",
4 | "compilerOptions": {
5 | "composite": false,
6 | "declaration": true,
7 | "declarationMap": true,
8 | "esModuleInterop": true,
9 | "jsx": "preserve",
10 | "allowJs": true,
11 | "strictFunctionTypes": false,
12 | "allowSyntheticDefaultImports": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "inlineSources": false,
15 | "isolatedModules": true,
16 | "moduleResolution": "node",
17 | "noUnusedLocals": false,
18 | "noUnusedParameters": false,
19 | "preserveWatchOutput": true,
20 | "skipLibCheck": true,
21 | "strict": true,
22 | "resolveJsonModule": true,
23 | "removeComments": true,
24 | "noImplicitAny": false,
25 | "experimentalDecorators": true
26 | },
27 | "exclude": ["**/node_modules/**", "**/dist/**"]
28 | }
29 |
--------------------------------------------------------------------------------
/configs/tsconfig/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tsconfig",
3 | "version": "0.0.0",
4 | "private": true,
5 | "files": [
6 | "base.json",
7 | "server.json"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/configs/tsconfig/server.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Server",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "module": "commonjs",
7 | "declaration": true,
8 | "experimentalDecorators": true,
9 | "emitDecoratorMetadata": true,
10 | "target": "esnext",
11 | "sourceMap": false,
12 | "lib": ["ESNext", "DOM"],
13 | "types": ["node"],
14 | "typeRoots": ["node_modules/@types/", "types"]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/configs/vite/build.config.ts:
--------------------------------------------------------------------------------
1 | import { defineBuildConfig } from 'unbuild'
2 |
3 | export default defineBuildConfig({
4 | clean: true,
5 | entries: ['src/index'],
6 | declaration: true,
7 | outDir: 'dist',
8 | rollup: {
9 | emitCJS: true,
10 | cjsBridge: true,
11 | },
12 | })
13 |
--------------------------------------------------------------------------------
/configs/vite/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@config/vite",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "dist/index.cjs",
6 | "types": "dist/index.d.ts",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo",
9 | "prepack": "pnpm unbuild --stub"
10 | },
11 | "dependencies": {
12 | "@ant-design/colors": "^6.0.0",
13 | "@vitejs/plugin-legacy": "^1.7.1",
14 | "@vitejs/plugin-vue": "^2.2.4",
15 | "@vitejs/plugin-vue-jsx": "^1.3.8",
16 | "dayjs": "^1.11.0",
17 | "less": "^4.1.2",
18 | "picocolors": "^1.0.0",
19 | "pkg-types": "^0.3.2",
20 | "rollup-plugin-visualizer": "^5.6.0",
21 | "tsconfig": "workspace:*",
22 | "vite": "2.9.0-beta.4",
23 | "vite-plugin-compression": "^0.5.1",
24 | "vite-plugin-html": "^3.2.0",
25 | "vite-plugin-imagemin": "^0.6.1",
26 | "vite-plugin-mkcert": "^1.6.0",
27 | "vite-plugin-mock": "^2.9.6",
28 | "vite-plugin-purge-icons": "^0.8.1",
29 | "vite-plugin-svg-icons": "^2.0.1",
30 | "vite-plugin-theme": "^0.8.6",
31 | "vite-plugin-vue-setup-extend": "^0.4.0"
32 | },
33 | "devDependencies": {
34 | "mockjs": "^1.1.0",
35 | "vue": "^3.2.31"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/configs/vite/src/constants.ts:
--------------------------------------------------------------------------------
1 | // The name of the configuration file entered in the production environment
2 | export const GLOB_CONFIG_FILE_NAME = '_app.config.js'
3 |
4 | // vite package output directory
5 | export const OUTPUT_DIR = 'dist'
6 |
--------------------------------------------------------------------------------
/configs/vite/src/plugins/compress.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
3 | * @see https://github.com/anncwb/vite-plugin-compression
4 | */
5 | import type { PluginOption } from 'vite'
6 | import compressPlugin from 'vite-plugin-compression'
7 |
8 | export function configCompressPlugin(
9 | compress: 'gzip' | 'brotli' | 'none',
10 | deleteOriginFile = false,
11 | ) {
12 | const compressList = compress.split(',')
13 |
14 | const plugins: PluginOption[] = []
15 |
16 | if (compressList.includes('gzip')) {
17 | plugins.push(compressPlugin({ deleteOriginFile }))
18 | }
19 |
20 | if (compressList.includes('brotli')) {
21 | plugins.push(
22 | compressPlugin({
23 | algorithm: 'brotliCompress',
24 | deleteOriginFile,
25 | }),
26 | )
27 | }
28 | return plugins
29 | }
30 |
--------------------------------------------------------------------------------
/configs/vite/src/plugins/imagemin.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Image resource files used to compress the output of the production environment
3 | * @see https://github.com/anncwb/vite-plugin-imagemin
4 | */
5 | import viteImagemin from 'vite-plugin-imagemin'
6 |
7 | export function configImageminPlugin() {
8 | return viteImagemin({
9 | gifsicle: {
10 | optimizationLevel: 7,
11 | interlaced: false,
12 | },
13 | optipng: {
14 | optimizationLevel: 7,
15 | },
16 | mozjpeg: {
17 | quality: 20,
18 | },
19 | pngquant: {
20 | quality: [0.8, 0.9],
21 | speed: 4,
22 | },
23 | svgo: {
24 | plugins: [
25 | {
26 | name: 'removeViewBox',
27 | },
28 | {
29 | name: 'removeEmptyAttrs',
30 | active: false,
31 | },
32 | ],
33 | },
34 | })
35 | }
36 |
--------------------------------------------------------------------------------
/configs/vite/src/plugins/mock.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Mock plugin for development and production.
3 | * @see https://github.com/anncwb/vite-plugin-mock
4 | */
5 | import { viteMockServe } from 'vite-plugin-mock'
6 |
7 | export function configMockPlugin(isBuild: boolean) {
8 | return viteMockServe({
9 | ignore: /^\_/,
10 | mockPath: 'mock',
11 | localEnabled: !isBuild,
12 | prodEnabled: isBuild,
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/configs/vite/src/plugins/svg-icons.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Vite Plugin for fast creating SVG sprites.
3 | * @see https://github.com/anncwb/vite-plugin-svg-icons
4 | */
5 |
6 | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
7 | import { resolve } from 'path'
8 |
9 | export function configSvgIconsPlugin(isBuild: boolean) {
10 | const svgIconsPlugin = createSvgIconsPlugin({
11 | iconDirs: [resolve(process.cwd(), 'src/assets/icons')],
12 | svgoOptions: isBuild,
13 | })
14 | return svgIconsPlugin
15 | }
16 |
--------------------------------------------------------------------------------
/configs/vite/src/plugins/visualizer.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Package file volume analysis
3 | * @see https://github.com/btd/rollup-plugin-visualizer
4 | */
5 | import type { PluginOption } from 'vite'
6 | import visualizer from 'rollup-plugin-visualizer'
7 |
8 | export function configVisualizerConfig(): PluginOption {
9 | if (process.env.REPORT === 'true') {
10 | return visualizer({
11 | filename: './node_modules/.cache/visualizer/stats.html',
12 | open: true,
13 | gzipSize: true,
14 | brotliSize: true,
15 | })
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/configs/vite/src/presets/ant/index.ts:
--------------------------------------------------------------------------------
1 | import type { UserConfig } from 'vite'
2 |
3 | export async function createAntdPreset(command: string): Promise {
4 | const { generateModifyVars } = await import('./modify-vars')
5 | const { configThemePlugin } = await import('./theme-plugin')
6 | return {
7 | plugins: [
8 | // vite-plugin-theme
9 | configThemePlugin(command === 'build'),
10 | ],
11 | optimizeDeps: {
12 | include: [
13 | '@ant-design/icons-vue',
14 | 'ant-design-vue/es/locale/zh_CN',
15 | 'ant-design-vue/es/locale/en_US',
16 | ],
17 | exclude: ['vue-demi'],
18 | },
19 | css: {
20 | preprocessorOptions: {
21 | less: {
22 | modifyVars: generateModifyVars(),
23 | javascriptEnabled: true,
24 | },
25 | },
26 | },
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/configs/vite/src/presets/index.ts:
--------------------------------------------------------------------------------
1 | import { createAntdPreset } from './ant'
2 |
3 | export type FrameworkType = 'ant'
4 |
5 | export function createPreset(framework: FrameworkType) {
6 | const presets = {
7 | ant: createAntdPreset,
8 | }
9 | return presets[framework]
10 | }
11 |
--------------------------------------------------------------------------------
/configs/vite/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig/base.json",
3 | "include": ["src"],
4 | "exclude": ["dist", "node_modules"]
5 | }
6 |
--------------------------------------------------------------------------------
/nswag/Templates/Client.Method.Documentation.liquid:
--------------------------------------------------------------------------------
1 | {% if operation.HasDocumentation -%}
2 | /**
3 | {% if operation.HasSummary -%}
4 | * {{ operation.Summary }}
5 | {% endif -%}
6 | {% for parameter in operation.Parameters -%}
7 | {% if parameter.HasDescriptionOrIsOptional -%}
8 | * @param {{ parameter.VariableName }}{% if parameter.IsOptional %} (optional){% endif %} {{ parameter.Description }}
9 | {% endif -%}
10 | {% endfor -%}
11 | {% if operation.HasResultDescription -%}
12 | * @return {{ operation.ResultDescription }}
13 | {% endif -%}
14 | {% if operation.IsDeprecated -%}
15 | * @deprecated
16 | {% endif -%}
17 | */
18 | {% endif -%}
--------------------------------------------------------------------------------
/nswag/Templates/Client.ProcessResponse.ReadBodyEnd.liquid:
--------------------------------------------------------------------------------
1 | {% if Framework.IsFetchOrAurelia or operation.RequestAngularBlobs or Framework.Angular.UseHttpClient or operation.RequestAngularJSBlobs -%}
2 | {% if Framework.IsAngular and Framework.UseRxJs6 and (Framework.Angular.UseHttpClient or operation.RequestAngularBlobs) -%}
3 | }));
4 | {% else -%}
5 | });
6 | {% endif -%}
7 | {% endif -%}
8 |
--------------------------------------------------------------------------------
/nswag/Templates/Client.ProcessResponse.ReadBodyStart.liquid:
--------------------------------------------------------------------------------
1 | {% if Framework.IsFetchOrAurelia -%}
2 | return response.text().then((_responseText) => {
3 | {% elseif Framework.Angular.UseHttpClient -%}
4 | {% if Framework.UseRxJs6 -%}
5 | return blobToText(responseBlob).pipe({{ Framework.RxJs.ObservableMergeMapMethod }}(_responseText => {
6 | {% else -%}
7 | return blobToText(responseBlob).flatMap(_responseText => {
8 | {% endif -%}
9 | {% elseif operation.RequestAngularBlobs -%}
10 | {% if Framework.UseRxJs6 -%}
11 | return blobToText(response.blob()).pipe({{ Framework.RxJs.ObservableMergeMapMethod }}(_responseText => {
12 | {% else -%}
13 | return blobToText(response.blob()).flatMap(_responseText => {
14 | {% endif -%}
15 | {% elseif operation.RequestAngularJSBlobs -%}
16 | return blobToText(new Blob([response]), this.q).then(_responseText => {
17 | {% elseif Framework.IsAngular -%}
18 | const _responseText = response.text();
19 | {% elseif Framework.IsAngularJS -%}
20 | const _responseText = response.data;
21 | {% elseif Framework.IsAxios -%}
22 | const _responseText = response.data.data;
23 | {% else -%}
24 | const _responseText = xhr.responseText;
25 | {% endif -%}
--------------------------------------------------------------------------------
/nswag/Templates/Client.ProcessResponse.ReadHeaders.liquid:
--------------------------------------------------------------------------------
1 | {% if Framework.IsAngular -%}
2 | {% if Framework.Angular.UseHttpClient -%}
3 | let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }};
4 | {% else -%}
5 | let _headers: any = response.headers ? response.headers.toJSON() : {};
6 | {% endif -%}
7 | {% elseif Framework.IsFetchOrAurelia -%}
8 | let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
9 | {% elseif Framework.IsAxios -%}
10 | let _headers: any = {};
11 | if (response.headers && typeof response.headers === "object") {
12 | for (let k in response.headers) {
13 | if (response.headers.hasOwnProperty(k)) {
14 | _headers[k] = response.headers[k];
15 | }
16 | }
17 | }
18 | {% else -%}
19 | let _headers: any = {};
20 | {% endif -%}
--------------------------------------------------------------------------------
/nswag/Templates/Client.ProcessResponse.liquid:
--------------------------------------------------------------------------------
1 | {% template Client.ProcessResponse.ReadHeaders %}
2 | {% if operation.HandleReferences and operation.RequiresMappings -%}
3 | let _mappings: { source: any, target: any }[] = [];
4 | {% endif -%}
5 | {% for response in operation.Responses -%}
6 | if (status === {{ response.StatusCode }}{% if response.CheckChunkedStatusCode %} || status === 206{% endif %}) {
7 | {% template Client.ProcessResponse.HandleStatusCode %}
8 | } else {% endfor -%}
9 | {% if operation.HasDefaultResponse -%}
10 | {
11 | {% assign response = operation.DefaultResponse -%}
12 | {% template Client.ProcessResponse.HandleStatusCode %}
13 | }
14 | {% else -%}
15 | if (status !== 200 && status !== 204) {
16 | {% template Client.ProcessResponse.ReadBodyStart %}
17 | return throwException({% if Framework.IsAngularJS %}this.q, {% endif %}"An unexpected server error occurred.", status, _responseText, _headers);
18 | {% template Client.ProcessResponse.ReadBodyEnd %}
19 | }
20 | {% template Client.ProcessResponse.Return %}
21 | {% endif -%}
--------------------------------------------------------------------------------
/nswag/refresh.bat:
--------------------------------------------------------------------------------
1 | "..\node_modules\.bin\nswag" run /runtime:NetCore31
2 |
--------------------------------------------------------------------------------
/packages/apis/account.ts:
--------------------------------------------------------------------------------
1 |
2 | // import { request } from '../request'
3 |
4 | // enum Api {
5 | // ACCOUNT_INFO = '/account/getAccountInfo',
6 | // SESSION_TIMEOUT = '/user/sessionTimeout',
7 | // TOKEN_EXPIRED = '/user/tokenExpired',
8 | // }
9 | // export interface GetAccountInfoModel {
10 | // email: string
11 | // name: string
12 | // introduction: string
13 | // phone: string
14 | // address: string
15 | // }
16 |
17 | // // Get personal center-basic settings
18 |
19 | // export const accountInfoApi = () =>
20 | // request.get({ url: Api.ACCOUNT_INFO })
21 |
22 | // export const sessionTimeoutApi = () =>
23 | // request.post({ url: Api.SESSION_TIMEOUT })
24 |
25 | // export const tokenExpiredApi = () =>
26 | // request.post({ url: Api.TOKEN_EXPIRED })
27 |
--------------------------------------------------------------------------------
/packages/apis/demo/account.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | export interface GetAccountInfoModel {
4 | email: string
5 | name: string
6 | introduction: string
7 | phone: string
8 | address: string
9 | }
10 |
11 | enum Api {
12 | ACCOUNT_INFO = '/account/getAccountInfo',
13 | SESSION_TIMEOUT = '/user/sessionTimeout',
14 | TOKEN_EXPIRED = '/user/tokenExpired',
15 | }
16 |
17 | // Get personal center-basic settings
18 |
19 | export const accountInfoApi = () =>
20 | request.get({ url: Api.ACCOUNT_INFO })
21 |
22 | export const sessionTimeoutApi = () =>
23 | request.post({ url: Api.SESSION_TIMEOUT })
24 |
25 | export const tokenExpiredApi = () =>
26 | request.post({ url: Api.TOKEN_EXPIRED })
27 |
--------------------------------------------------------------------------------
/packages/apis/demo/cascader.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | export interface AreaModel {
4 | id: string
5 | code: string
6 | parentCode: string
7 | name: string
8 | levelType: number
9 | [key: string]: string | number
10 | }
11 |
12 | export interface AreaParams {
13 | parentCode: string
14 | }
15 |
16 | enum Api {
17 | AREA_RECORD = '/cascader/getAreaRecord',
18 | }
19 |
20 | export const areaRecord = (data: AreaParams) =>
21 | request.post({ url: Api.AREA_RECORD, data })
22 |
--------------------------------------------------------------------------------
/packages/apis/demo/error.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | enum Api {
4 | // The address does not exist
5 | Error = '/error',
6 | }
7 |
8 | /**
9 | * @description: Trigger ajax error
10 | */
11 |
12 | export const fireErrorApi = () => request.get({ url: Api.Error })
13 |
--------------------------------------------------------------------------------
/packages/apis/demo/index.ts:
--------------------------------------------------------------------------------
1 | export * from './account'
2 | export * from './cascader'
3 | export * from './error'
4 | export * from './select'
5 | // export * from './system'
6 | export * from './table'
7 | export * from './tree'
8 |
--------------------------------------------------------------------------------
/packages/apis/demo/select.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | export interface DemoOptionsItem {
4 | label: string
5 | value: string
6 | }
7 |
8 | export interface SelectParams {
9 | id: number | string
10 | }
11 |
12 | enum Api {
13 | OPTIONS_LIST = '/select/getDemoOptions',
14 | }
15 |
16 | /**
17 | * @description: Get sample options value
18 | */
19 | export const optionsListApi = (params?: SelectParams) =>
20 | request.get({ url: Api.OPTIONS_LIST, params })
21 |
--------------------------------------------------------------------------------
/packages/apis/demo/table.ts:
--------------------------------------------------------------------------------
1 | import type { BasicPageParams, BasicFetchResult } from '../types'
2 | import { request } from '@pkg/request'
3 |
4 | /**
5 | * @description: Request list interface parameters
6 | */
7 | export type DemoParams = BasicPageParams
8 |
9 | export interface DemoListItem {
10 | id: string
11 | beginTime: string
12 | endTime: string
13 | address: string
14 | name: string
15 | no: number
16 | status: number
17 | }
18 |
19 | /**
20 | * @description: Request list return value
21 | */
22 | export type DemoListGetResultModel = BasicFetchResult
23 |
24 | enum Api {
25 | DEMO_LIST = '/table/getDemoList',
26 | }
27 |
28 | /**
29 | * @description: Get sample list value
30 | */
31 |
32 | export const demoListApi = (params: DemoParams) =>
33 | request.get({
34 | url: Api.DEMO_LIST,
35 | params,
36 | headers: {
37 | // @ts-ignore
38 | ignoreCancelToken: true,
39 | },
40 | })
41 |
--------------------------------------------------------------------------------
/packages/apis/demo/tree.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | enum Api {
4 | TREE_OPTIONS_LIST = '/tree/getDemoOptions',
5 | }
6 |
7 | /**
8 | * @description: Get sample options value
9 | */
10 | export const treeOptionsListApi = (params?: Recordable) =>
11 | request.get({ url: Api.TREE_OPTIONS_LIST, params })
12 |
--------------------------------------------------------------------------------
/packages/apis/develop.ts:
--------------------------------------------------------------------------------
1 | import { ContentTypeManagementServiceProxy, Stereotype } from './eoc/app-service-proxies'
2 |
3 | export async function getAllTypes(params: {
4 | stereotype: number | Stereotype
5 | filter: string | undefined
6 | page: number | undefined
7 | pageSize: number | undefined
8 | }) {
9 | const data = await new ContentTypeManagementServiceProxy().getAllTypes(params)
10 | console.log(data, 'getAllTypes')
11 | return data
12 | }
13 |
--------------------------------------------------------------------------------
/packages/apis/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/apis",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/request": "workspace:*",
12 | "@pkg/types": "workspace:*"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/apis/sys/index.ts:
--------------------------------------------------------------------------------
1 | export * from './menu'
2 | export * from './upload'
3 | export * from './user'
4 |
--------------------------------------------------------------------------------
/packages/apis/sys/menu.ts:
--------------------------------------------------------------------------------
1 | import { request } from '@pkg/request'
2 |
3 | export interface RouteItem {
4 | path: string
5 | component: any
6 | meta: any
7 | name?: string
8 | alias?: string | string[]
9 | redirect?: string
10 | caseSensitive?: boolean
11 | children?: RouteItem[]
12 | }
13 |
14 |
15 | /**
16 | * @description: Get menu return value
17 | */
18 | export type GetMenuListResultModel = RouteItem[]
19 |
20 | enum Api {
21 | GetMenuList = '/getMenuList',
22 | }
23 |
24 | /**
25 | * @description: Get user menu based on id
26 | */
27 |
28 | export const getMenuList = () => {
29 | return request.get({ url: Api.GetMenuList })
30 | }
31 |
--------------------------------------------------------------------------------
/packages/apis/sys/upload.ts:
--------------------------------------------------------------------------------
1 | import type { RequestUploadFileOptions } from '@pkg/types'
2 | import { request } from '@pkg/request'
3 |
4 | export interface UploadApiResult {
5 | message: string
6 | code: number
7 | url: string
8 | }
9 |
10 | /**
11 | * @description: Upload interface
12 | */
13 | export function uploadApi(
14 | params: RequestUploadFileOptions,
15 | onUploadProgress: (progressEvent: ProgressEvent) => void,
16 | ) {
17 | return request.uploadFile(
18 | {
19 | // TODO
20 | // url: context.uploadUrl,
21 | onUploadProgress,
22 | },
23 | params,
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/packages/apis/types.ts:
--------------------------------------------------------------------------------
1 | export interface BasicPageParams {
2 | page: number
3 | pageSize: number
4 | }
5 |
6 | export interface BasicFetchResult {
7 | items: T[]
8 | total: number
9 | }
10 |
--------------------------------------------------------------------------------
/packages/components/antd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@components/antd",
3 | "version": "3.0.0-alpha.4",
4 | "license": "MIT",
5 | "scripts": {
6 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/components/common/index.ts:
--------------------------------------------------------------------------------
1 | export { default as CountTo } from './count-to/index.vue'
2 | export { default as SvgIcon } from './svg-icon/index.vue'
3 | export { default as Icon } from './icon/index.vue'
4 | export { default as Time } from './time/index.vue'
5 | export { default as CollapseTransition } from './transition/collapse-transition.vue'
6 |
7 | export { default as QrCode } from './qrcode/index.vue'
8 | export type { QrCodeActionType } from './qrcode/typing'
9 |
--------------------------------------------------------------------------------
/packages/components/common/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@components/common",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/locale": "workspace:*",
12 | "@pkg/use": "workspace:*",
13 | "@pkg/utils": "workspace:*",
14 | "qrcode": "^1.5.0"
15 | },
16 | "devDependencies": {
17 | "@types/qrcode": "^1.4.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/components/common/qrcode/to-canvas.ts:
--------------------------------------------------------------------------------
1 | import type { RenderQrCodeParams } from './typing'
2 | import { renderQrCode } from './draw-canvas'
3 | import { drawLogo } from './draw-logo'
4 |
5 | export const toCanvas = (options: RenderQrCodeParams) => {
6 | return renderQrCode(options)
7 | .then(() => {
8 | return options
9 | })
10 | .then(drawLogo) as Promise
11 | }
12 |
--------------------------------------------------------------------------------
/packages/components/common/qrcode/typing.ts:
--------------------------------------------------------------------------------
1 | import type { QRCodeSegment, QRCodeRenderersOptions } from 'qrcode'
2 |
3 | export type ContentType = string | QRCodeSegment[]
4 | export type { QRCodeRenderersOptions }
5 |
6 | export type LogoType = {
7 | src: string
8 | logoSize: number
9 | borderColor: string
10 | bgColor: string
11 | borderSize: number
12 | crossOrigin: string
13 | borderRadius: number
14 | logoRadius: number
15 | }
16 |
17 | export interface RenderQrCodeParams {
18 | canvas: any
19 | content: ContentType
20 | width?: number
21 | options?: QRCodeRenderersOptions
22 | logo?: LogoType | string
23 | image?: HTMLImageElement
24 | downloadName?: string
25 | download?: boolean | AnyFunction
26 | }
27 |
28 | export type ToCanvasFn = (options: RenderQrCodeParams) => Promise
29 |
30 | export interface QrCodeActionType {
31 | download: (fileName?: string) => void
32 | }
33 |
34 | export interface QrcodeDoneEventParams {
35 | url: string
36 | ctx?: CanvasRenderingContext2D | null
37 | }
38 |
--------------------------------------------------------------------------------
/packages/directives/bridge.ts:
--------------------------------------------------------------------------------
1 | import { RoleEnum } from '@pkg/tokens'
2 |
3 | export interface ContextOptions {
4 | hasPermission: (
5 | value?: string | RoleEnum[] | string[] | undefined,
6 | def?: boolean,
7 | ) => boolean
8 | createLoading: AnyFunction
9 | }
10 |
11 | export let context: ContextOptions = {
12 | hasPermission: () => false,
13 | createLoading: () => {},
14 | }
15 |
16 | export const initDirective = async (_context: ContextOptions) => {
17 | context = _context
18 | }
19 |
--------------------------------------------------------------------------------
/packages/directives/index.ts:
--------------------------------------------------------------------------------
1 | import type { App } from 'vue'
2 | import { loading } from './src/loading'
3 | import { auth } from './src/auth'
4 |
5 | export { clickOutside } from './src/click-outside'
6 | export { auth, loading }
7 | export * from './bridge'
8 |
9 | export const registerGlobalDirective = (app: App) => {
10 | app.directive('loading', loading)
11 | app.directive('auth', auth)
12 | }
13 |
--------------------------------------------------------------------------------
/packages/directives/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/directives",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "types": "index.d.js",
7 | "unpkg": "index.js",
8 | "jsdelivr": "index.js",
9 | "license": "MIT",
10 | "scripts": {
11 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
12 | },
13 | "dependencies": {
14 | "@pkg/utils": "workspace:*",
15 | "@pkg/tokens": "workspace:*"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/directives/src/auth.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Global authority directive
3 | * Used for fine-grained control of component permissions
4 | * @Example v-auth="RoleEnum.TEST"
5 | */
6 | import type { Directive, DirectiveBinding } from 'vue'
7 |
8 | import { context } from '../bridge'
9 |
10 | const isAuth = (el: Element, binding: any) => {
11 | const value = binding.value
12 | if (!value) return
13 | if (!context.hasPermission(value)) {
14 | el.parentNode?.removeChild(el)
15 | }
16 | }
17 |
18 | const mounted = (el: Element, binding: DirectiveBinding) => {
19 | isAuth(el, binding)
20 | }
21 |
22 | const auth: Directive = {
23 | mounted,
24 | }
25 |
26 | export { auth }
27 |
--------------------------------------------------------------------------------
/packages/directives/src/loading.ts:
--------------------------------------------------------------------------------
1 | import type { Directive } from 'vue'
2 |
3 | import { context } from '../bridge'
4 |
5 | const loading: Directive = {
6 | mounted(el, binding) {
7 | const tip = el.getAttribute('loading-tip')
8 | const background = el.getAttribute('loading-background')
9 | const size = el.getAttribute('loading-size')
10 | const fullscreen = !!binding.modifiers.fullscreen
11 | const instance = context.createLoading(
12 | {
13 | tip,
14 | background,
15 | size: size || 'large',
16 | loading: !!binding.value,
17 | absolute: !fullscreen,
18 | },
19 | fullscreen ? document.body : el,
20 | )
21 | el.instance = instance
22 | },
23 | updated(el, binding) {
24 | const instance = el.instance
25 | if (!instance) return
26 | instance.setTip(el.getAttribute('loading-tip'))
27 | if (binding.oldValue !== binding.value) {
28 | instance.setLoading?.(binding.value && !instance.loading)
29 | }
30 | },
31 | unmounted(el) {
32 | el?.instance?.close()
33 | },
34 | }
35 |
36 | export { loading }
37 |
--------------------------------------------------------------------------------
/packages/locale/index.ts:
--------------------------------------------------------------------------------
1 | export { setupI18n } from './src/setup-i18n'
2 | export { useI18n, t } from './src/use-i18n'
3 | export { useLocale } from './src/use-locale'
4 | export { showLocalePicker } from './src/store'
5 |
--------------------------------------------------------------------------------
/packages/locale/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/locale",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "optionalDependencies": {
11 | "vue": "^3.2.31"
12 | },
13 | "dependencies": {
14 | "@pkg/setting": "workspace:*",
15 | "@pkg/tokens": "workspace:*",
16 | "@pkg/types": "workspace:*",
17 | "@pkg/utils": "workspace:*",
18 | "@vueuse/core": "^8.1.2",
19 | "vue-i18n": "^9.1.9"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/en.ts:
--------------------------------------------------------------------------------
1 | import { genMessage } from '../helper'
2 |
3 | const modules = import.meta.globEager('./en/**/*.ts')
4 | export default {
5 | message: {
6 | ...genMessage(modules, 'en'),
7 | },
8 | dateLocale: null,
9 | dateLocaleName: 'en',
10 | }
11 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/en/common.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | okText: 'OK',
3 | closeText: 'Close',
4 | cancelText: 'Cancel',
5 | loadingText: 'Loading...',
6 | saveText: 'Save',
7 | delText: 'Delete',
8 | resetText: 'Reset',
9 | searchText: 'Search',
10 | queryText: 'Search',
11 |
12 | inputText: 'Please enter',
13 | chooseText: 'Please choose',
14 |
15 | redo: 'Refresh',
16 | back: 'Back',
17 |
18 | light: 'Light',
19 | dark: 'Dark',
20 | }
21 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/en/routes/basic.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | login: 'Login',
3 | }
4 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/en/routes/dashboard.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | dashboard: 'Dashboard',
3 | about: 'About',
4 | workbench: 'Workbench',
5 | analysis: 'Analysis',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/en/routes/develop.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | develop: '开发',
3 | type: '类型',
4 | }
5 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/common.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | okText: '确认',
3 | closeText: '关闭',
4 | cancelText: '取消',
5 | loadingText: '加载中...',
6 | saveText: '保存',
7 | delText: '删除',
8 | resetText: '重置',
9 | searchText: '搜索',
10 | queryText: '查询',
11 |
12 | inputText: '请输入',
13 | chooseText: '请选择',
14 |
15 | redo: '刷新',
16 | back: '返回',
17 |
18 | light: '亮色主题',
19 | dark: '黑暗主题',
20 | }
21 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/routes/amis.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | amis: 'AMIS',
3 | amisIndex: '页面辑器',
4 | amisPageList: '动态页管理',
5 | Internal: '编辑器(内嵌)',
6 | amisEditor: '页面辑器',
7 | AmisDynamic: '动态架构',
8 | AmisPreview: '动态页预览',
9 | }
10 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/routes/basic.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | login: '登录',
3 | }
4 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/routes/crm.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | crm: 'CRM',
3 | customer: '客户',
4 | }
5 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/routes/dashboard.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | dashboard: 'Dashboard',
3 | about: '关于',
4 | workbench: '工作台',
5 | analysis: '分析页',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh-CN/routes/develop.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | develop: '开发',
3 | type: '类型',
4 | listManagement: '列表管理',
5 | listDetails: '新建列表',
6 | }
7 |
--------------------------------------------------------------------------------
/packages/locale/src/lang/zh_CN.ts:
--------------------------------------------------------------------------------
1 | import { genMessage } from '../helper'
2 |
3 | const modules = import.meta.globEager('./zh-CN/**/*.ts')
4 | export default {
5 | message: {
6 | ...genMessage(modules, 'zh-CN'),
7 | },
8 | }
9 |
--------------------------------------------------------------------------------
/packages/locale/src/store.ts:
--------------------------------------------------------------------------------
1 | import type { LocaleType } from '@pkg/types'
2 |
3 | import { computed } from 'vue'
4 | import { LOCALE_KEY } from '@pkg/tokens'
5 | import { useLocalStorage } from '@vueuse/core'
6 | import { localeSetting } from '@pkg/setting'
7 |
8 | const store = useLocalStorage(LOCALE_KEY, localeSetting)
9 |
10 | export const setLocale = (locale: LocaleType) => {
11 | store.value.locale = locale
12 | }
13 |
14 | export const getLocale = computed(() => store.value.locale)
15 |
16 | export const showLocalePicker = computed(() => store.value.showPicker)
17 |
--------------------------------------------------------------------------------
/packages/locale/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tsconfig/base.json",
3 | "compilerOptions": {
4 | "target": "esnext",
5 | "module": "esnext",
6 | "baseUrl": ".",
7 | "paths": {
8 | "@/*": ["src/*"]
9 | },
10 | "lib": ["dom", "esnext"],
11 | "types": ["vite/client"]
12 | },
13 | "include": ["src"],
14 | "exclude": ["**/node_modules/**", "**/dist/**"]
15 | }
16 |
--------------------------------------------------------------------------------
/packages/request/index.ts:
--------------------------------------------------------------------------------
1 | export { initRequest } from './bridge'
2 | export { AxiosCanceler as RequestCanceler } from './src/axiosCancel'
3 | export { request, ocApi } from './src/index'
4 |
--------------------------------------------------------------------------------
/packages/request/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/request",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/locale": "workspace:*",
12 | "@pkg/tokens": "workspace:*",
13 | "@pkg/types": "workspace:*",
14 | "@pkg/utils": "workspace:*",
15 | "axios": "^0.26.1",
16 | "qs": "^6.10.3"
17 | },
18 | "devDependencies": {
19 | "@types/qs": "^6.9.7"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/setting/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src'
2 |
--------------------------------------------------------------------------------
/packages/setting/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/setting",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/tokens": "workspace:*",
12 | "@pkg/types": "workspace:*"
13 | },
14 | "optionalDependencies": {
15 | "vue": "^3.2.31"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/setting/src/design.ts:
--------------------------------------------------------------------------------
1 | import { ThemeEnum } from '@pkg/tokens'
2 |
3 | export const namespace = 'vben'
4 |
5 | export const primaryColor = '#0960bd'
6 |
7 | export const darkMode = ThemeEnum.LIGHT
8 |
9 | // app theme preset color
10 | export const APP_PRESET_COLOR_LIST: string[] = [
11 | '#0960bd',
12 | '#0084f4',
13 | '#009688',
14 | '#536dfe',
15 | '#ff5c93',
16 | '#ee4f12',
17 | '#0096c7',
18 | '#9c27b0',
19 | '#ff9800',
20 | ]
21 |
22 | // header preset color
23 | export const HEADER_PRESET_BG_COLOR_LIST: string[] = [
24 | '#ffffff',
25 | '#151515',
26 | '#009688',
27 | '#5172DC',
28 | '#018ffb',
29 | '#409eff',
30 | '#e74c3c',
31 | '#24292e',
32 | '#394664',
33 | '#001529',
34 | '#383f45',
35 | ]
36 |
37 | // sider preset color
38 | export const SIDE_BAR_BG_COLOR_LIST: string[] = [
39 | '#001529',
40 | '#212121',
41 | '#273352',
42 | '#ffffff',
43 | '#191b24',
44 | '#191a23',
45 | '#304156',
46 | '#001628',
47 | '#28333E',
48 | '#344058',
49 | '#383f45',
50 | ]
51 |
--------------------------------------------------------------------------------
/packages/setting/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './locale'
2 | export * from './design'
3 | export * from './component'
4 | export * from './site'
5 | export * from './project'
6 |
--------------------------------------------------------------------------------
/packages/setting/src/locale.ts:
--------------------------------------------------------------------------------
1 | import type { LocaleSetting, LocaleType } from '@pkg/types'
2 |
3 | export const LOCALE: { [key: string]: LocaleType } = {
4 | zh: 'zh_CN',
5 | en: 'en',
6 | }
7 |
8 | export const localeSetting: LocaleSetting = {
9 | showPicker: true,
10 | // Locale
11 | locale: LOCALE.zh,
12 | // Default locale
13 | fallback: LOCALE.zh,
14 | // available Locales
15 | availableLocales: [LOCALE.zh, LOCALE.en],
16 | }
17 |
18 | // locale list
19 | export const localeList: any[] = [
20 | {
21 | text: '简体中文',
22 | event: LOCALE.zh,
23 | },
24 | {
25 | text: 'English',
26 | event: LOCALE.en,
27 | },
28 | ]
29 |
--------------------------------------------------------------------------------
/packages/setting/src/site.ts:
--------------------------------------------------------------------------------
1 | // github repo url
2 | export const GITHUB_URL = 'https://github.com/anncwb/vue-vben-admin'
3 |
4 | // vue-vben-admin-next-doc
5 | export const DOC_URL = 'https://vvbin.cn/doc-next/'
6 |
7 | // site url
8 | export const SITE_URL = 'https://vvbin.cn/next/'
9 |
--------------------------------------------------------------------------------
/packages/styles/common/color.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/packages/styles/common/color.css
--------------------------------------------------------------------------------
/packages/styles/common/common.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EasyOC/EasyOC.VbenAdmin/4f711c4e480be3274e4ed6b68532834fd443acc3/packages/styles/common/common.css
--------------------------------------------------------------------------------
/packages/styles/common/index.ts:
--------------------------------------------------------------------------------
1 | import './common.css'
2 | import './tailwind.css'
3 |
--------------------------------------------------------------------------------
/packages/styles/common/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/packages/styles/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/styles",
3 | "version": "3.0.0-alpha.4",
4 | "license": "MIT",
5 | "scripts": {
6 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/tokens/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src'
2 |
--------------------------------------------------------------------------------
/packages/tokens/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/tokens",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/tokens/src/cache.ts:
--------------------------------------------------------------------------------
1 | // token key
2 | export const TOKEN_KEY = 'TOKEN'
3 |
4 | export const LOCALE_KEY = 'LOCALE'
5 |
6 | // user info key
7 | export const USER_INFO_KEY = 'USER__INFO'
8 |
9 | // role info key
10 | export const ROLES_KEY = 'ROLES__KEY'
11 |
12 | // project config key
13 | export const PROJ_CFG_KEY = 'PROJ__CFG__KEY'
14 |
15 | // lock info
16 | export const LOCK_INFO_KEY = 'LOCK__INFO__KEY'
17 |
18 | export const MULTIPLE_TABS_KEY = 'MULTIPLE_TABS__KEY'
19 |
20 | export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE'
21 |
22 | // base global local key
23 | export const APP_LOCAL_CACHE_KEY = 'COMMON__LOCAL__KEY'
24 |
25 | // base global session key
26 | export const APP_SESSION_CACHE_KEY = 'COMMON__SESSION__KEY'
27 |
28 | export enum CacheTypeEnum {
29 | SESSION,
30 | LOCAL,
31 | }
32 |
--------------------------------------------------------------------------------
/packages/tokens/src/enums/breakpoint.ts:
--------------------------------------------------------------------------------
1 | export enum ScreenSizeEnum {
2 | XS = 'XS',
3 | SM = 'SM',
4 | MD = 'MD',
5 | LG = 'LG',
6 | XL = 'XL',
7 | XXL = 'XXL',
8 | }
9 |
10 | export enum ScreenValueEnum {
11 | XS = 480,
12 | SM = 576,
13 | MD = 768,
14 | LG = 992,
15 | XL = 1200,
16 | XXL = 1600,
17 | }
18 |
19 | const screenMap = new Map()
20 |
21 | screenMap.set(ScreenSizeEnum.XS, ScreenValueEnum.XS)
22 | screenMap.set(ScreenSizeEnum.SM, ScreenValueEnum.SM)
23 | screenMap.set(ScreenSizeEnum.MD, ScreenValueEnum.MD)
24 | screenMap.set(ScreenSizeEnum.LG, ScreenValueEnum.LG)
25 | screenMap.set(ScreenSizeEnum.XL, ScreenValueEnum.XL)
26 | screenMap.set(ScreenSizeEnum.XXL, ScreenValueEnum.XXL)
27 |
28 | export { screenMap }
29 |
--------------------------------------------------------------------------------
/packages/tokens/src/enums/http.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * @description: Request result set
4 | */
5 | export enum ResultEnum {
6 | SUCCESS = 200,
7 | ERROR = 1,
8 | TIMEOUT = 401,
9 | TYPE = 'success',
10 | }
11 |
12 | /**
13 | * @description: request method
14 | */
15 | export enum RequestEnum {
16 | GET = 'GET',
17 | POST = 'POST',
18 | PUT = 'PUT',
19 | DELETE = 'DELETE',
20 | }
21 |
22 | /**
23 | * @description: contentType
24 | */
25 | export enum ContentTypeEnum {
26 | // json
27 | JSON = 'application/json;charset=UTF-8',
28 | // form-data qs
29 | FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
30 | // form-data upload
31 | FORM_DATA = 'multipart/form-data;charset=UTF-8',
32 | }
33 |
34 | /**
35 | * Exception related enumeration
36 | */
37 | export enum ExceptionEnum {
38 | // page not access
39 | PAGE_NOT_ACCESS = 403,
40 |
41 | // page not found
42 | PAGE_NOT_FOUND = 404,
43 |
44 | // error
45 | ERROR = 500,
46 |
47 | // net work error
48 | NET_WORK_ERROR = 10000,
49 |
50 | // No data on the page. In fact, it is not an exception page
51 | PAGE_NOT_DATA = 10100,
52 | }
53 |
--------------------------------------------------------------------------------
/packages/tokens/src/enums/menu.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @description: menu type
3 | */
4 | export enum MenuTypeEnum {
5 | // left menu
6 | SIDEBAR = 'sidebar',
7 |
8 | MIX_SIDEBAR = 'mix-sidebar',
9 | // mixin menu
10 | MIX = 'mix',
11 | // top menu
12 | TOP_MENU = 'top-menu',
13 | }
14 |
15 | // 折叠触发器位置
16 | export enum TriggerEnum {
17 | // 不显示
18 | NONE = 'NONE',
19 | // 菜单底部
20 | FOOTER = 'FOOTER',
21 | // 头部
22 | HEADER = 'HEADER',
23 | }
24 |
25 | export type Mode = 'vertical' | 'vertical-right' | 'horizontal' | 'inline'
26 |
27 | // menu mode
28 | export enum MenuModeEnum {
29 | VERTICAL = 'vertical',
30 | HORIZONTAL = 'horizontal',
31 | VERTICAL_RIGHT = 'vertical-right',
32 | INLINE = 'inline',
33 | }
34 |
35 | export enum MenuSplitTyeEnum {
36 | NONE,
37 | TOP,
38 | LEFT,
39 | }
40 |
41 | export enum TopMenuAlignEnum {
42 | CENTER = 'center',
43 | START = 'start',
44 | END = 'end',
45 | }
46 |
47 | export enum MixSidebarTriggerEnum {
48 | HOVER = 'hover',
49 | CLICK = 'click',
50 | }
51 |
--------------------------------------------------------------------------------
/packages/tokens/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './enums'
2 | export * from './cache'
3 | export * from './sidebar'
4 | export * from './router'
5 |
--------------------------------------------------------------------------------
/packages/tokens/src/router.ts:
--------------------------------------------------------------------------------
1 | export const REDIRECT_NAME = 'Redirect'
2 |
3 | export const PAGE_NOT_FOUND_NAME = 'PageNotFound'
4 |
--------------------------------------------------------------------------------
/packages/tokens/src/sidebar.ts:
--------------------------------------------------------------------------------
1 | export const SIDE_BAR_MINI_WIDTH = 48
2 | export const SIDE_BAR_SHOW_TIT_MINI_WIDTH = 80
3 |
--------------------------------------------------------------------------------
/packages/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src'
2 |
--------------------------------------------------------------------------------
/packages/types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/types",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/tokens": "workspace:*"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/types/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './util'
2 | export * from './config'
3 | export * from './store'
4 | export * from './service'
5 | export * from './shims'
6 | export * from './router'
7 | export * from './global'
8 |
--------------------------------------------------------------------------------
/packages/types/src/router.ts:
--------------------------------------------------------------------------------
1 | import type { RouteRecordRaw, RouteMeta, RouteComponent } from 'vue-router'
2 |
3 | type Lazy = () => Promise
4 |
5 | export type RouteRecordItem = {
6 | path: string
7 | orderNo?: number
8 | name: string
9 | meta: RouteMeta
10 | children?: RouteRecordItem[]
11 | component?: RouteComponent | Lazy | string
12 | } & RouteRecordRaw
13 |
--------------------------------------------------------------------------------
/packages/types/src/shims/index.ts:
--------------------------------------------------------------------------------
1 | import './module'
2 |
3 | export * from './vue-router'
4 | export * from './pinia'
5 |
--------------------------------------------------------------------------------
/packages/types/src/shims/module.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import { DefineComponent } from 'vue'
3 | const Component: DefineComponent<{}, {}, any>
4 | export default Component
5 | }
6 |
7 | declare module 'virtual:*' {
8 | const result: any
9 | export default result
10 | }
11 |
--------------------------------------------------------------------------------
/packages/types/src/shims/pinia.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore
2 | // eslint-disable-next-line
3 | import type { PiniaPluginContext } from 'pinia'
4 |
5 | declare module 'pinia' {
6 | export interface DefineStoreOptions<
7 | // eslint-disable-next-line
8 | Id,
9 | // eslint-disable-next-line
10 | S,
11 | // eslint-disable-next-line
12 | G,
13 | // eslint-disable-next-line
14 | A,
15 | > {
16 | /**
17 | * Persist store in storage.
18 | */
19 | persist?: PersistOptions
20 | }
21 | }
22 |
23 | export interface PersistStrategy {
24 | key?: string
25 | storage?: Storage
26 | paths?: string[]
27 | }
28 |
29 | export interface PersistOptions {
30 | strategies?: PersistStrategy[]
31 | }
32 |
--------------------------------------------------------------------------------
/packages/types/src/util.ts:
--------------------------------------------------------------------------------
1 | import type { ComputedRef, Ref } from 'vue'
2 |
3 | export type DynamicProps = {
4 | [P in keyof T]: Ref | T[P] | ComputedRef
5 | }
6 |
--------------------------------------------------------------------------------
/packages/use/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src'
2 |
3 | export {
4 | useTimeoutFn,
5 | useThrottleFn,
6 | useDebounceFn,
7 | onKeyStroke,
8 | onClickOutside,
9 | useTransition,
10 | TransitionPresets,
11 | useMutationObserver,
12 | useFullscreen,
13 | useIntervalFn,
14 | useWebSocket,
15 | useLocalStorage,
16 | } from '@vueuse/core'
17 |
--------------------------------------------------------------------------------
/packages/use/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/use",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/locale": "workspace:*",
12 | "@pkg/utils": "workspace:*",
13 | "@vueuse/core": "^8.1.2"
14 | },
15 | "optionalDependencies": {
16 | "vue": "^3.2.31"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/use/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './use-attrs'
2 | export * from './use-context'
3 | export * from './use-refs'
4 | export * from './use-pagination'
5 | export * from './use-script'
6 | export * from './use-watermark'
7 | export * from './use-title'
8 | export * from './use-window-resize'
9 |
--------------------------------------------------------------------------------
/packages/use/src/use-context.ts:
--------------------------------------------------------------------------------
1 | import {
2 | InjectionKey,
3 | provide,
4 | inject,
5 | reactive,
6 | readonly as defineReadonly,
7 | UnwrapRef,
8 | } from 'vue'
9 |
10 | export interface CreateContextOptions {
11 | readonly?: boolean
12 | createProvider?: boolean
13 | native?: boolean
14 | }
15 |
16 | type ShallowUnwrap = {
17 | [P in keyof T]: UnwrapRef
18 | }
19 |
20 | export const createContext = (
21 | context: any,
22 | key: InjectionKey = Symbol(),
23 | options: CreateContextOptions = {},
24 | ) => {
25 | const { readonly = true, createProvider = false, native = false } = options
26 |
27 | const state = reactive(context)
28 | const provideData = readonly ? defineReadonly(state) : state
29 | !createProvider && provide(key, native ? context : provideData)
30 |
31 | return { state }
32 | }
33 |
34 | export function useContext(key: InjectionKey, native?: boolean): T
35 | export function useContext(
36 | key: InjectionKey,
37 | defaultValue?: any,
38 | native?: boolean,
39 | ): T
40 |
41 | export function useContext(
42 | key: InjectionKey = Symbol(),
43 | defaultValue?: any,
44 | ): ShallowUnwrap {
45 | return inject(key, defaultValue || {})
46 | }
47 |
--------------------------------------------------------------------------------
/packages/use/src/use-pagination.ts:
--------------------------------------------------------------------------------
1 | import type { Ref } from 'vue'
2 | import { ref, unref, computed } from 'vue'
3 |
4 | const pagination = (
5 | list: T[],
6 | pageNo: number,
7 | pageSize: number,
8 | ): T[] => {
9 | const offset = (pageNo - 1) * Number(pageSize)
10 | const ret =
11 | offset + Number(pageSize) >= list.length
12 | ? list.slice(offset, list.length)
13 | : list.slice(offset, offset + Number(pageSize))
14 | return ret
15 | }
16 |
17 | export const usePagination = (list: Ref, pageSize: number) => {
18 | const currentPage = ref(1)
19 | const pageSizeRef = ref(pageSize)
20 |
21 | const getPaginationList = computed(() => {
22 | return pagination(unref(list), unref(currentPage), unref(pageSizeRef))
23 | })
24 |
25 | const getTotal = computed(() => {
26 | return unref(list).length
27 | })
28 |
29 | function setCurrentPage(page: number) {
30 | currentPage.value = page
31 | }
32 |
33 | function setPageSize(pageSize: number) {
34 | pageSizeRef.value = pageSize
35 | }
36 |
37 | return { setCurrentPage, getTotal, setPageSize, getPaginationList }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/use/src/use-refs.ts:
--------------------------------------------------------------------------------
1 | import type { Ref } from 'vue'
2 | import { ref, onBeforeUpdate } from 'vue'
3 |
4 | export const useRefs = (): [
5 | Ref,
6 | (index: number) => (el: HTMLElement) => void,
7 | ] => {
8 | const refs = ref([]) as Ref
9 |
10 | onBeforeUpdate(() => {
11 | refs.value = []
12 | })
13 |
14 | const setRefs = (index: number) => (el: HTMLElement) => {
15 | refs.value[index] = el
16 | }
17 |
18 | return [refs, setRefs]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/use/src/use-script.ts:
--------------------------------------------------------------------------------
1 | import { onMounted, onUnmounted, ref } from 'vue'
2 |
3 | interface ScriptOptions {
4 | src: string
5 | }
6 |
7 | export const useScript = (opts: ScriptOptions) => {
8 | const isLoading = ref(false)
9 | const error = ref(false)
10 | const success = ref(false)
11 | let script: HTMLScriptElement
12 |
13 | const promise = new Promise((resolve, reject) => {
14 | onMounted(() => {
15 | script = document.createElement('script')
16 | script.type = 'text/javascript'
17 | script.onload = function () {
18 | isLoading.value = false
19 | success.value = true
20 | error.value = false
21 | resolve('')
22 | }
23 |
24 | script.onerror = function (err) {
25 | isLoading.value = false
26 | success.value = false
27 | error.value = true
28 | reject(err)
29 | }
30 |
31 | script.src = opts.src
32 | document.head.appendChild(script)
33 | })
34 | })
35 |
36 | onUnmounted(() => {
37 | script && script.remove()
38 | })
39 |
40 | return {
41 | isLoading,
42 | error,
43 | success,
44 | toPromise: () => promise,
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/use/src/use-title.ts:
--------------------------------------------------------------------------------
1 | import type { RouteLocationNormalizedLoaded } from 'vue-router'
2 |
3 | import { watch, unref } from 'vue'
4 | import { useRouter } from 'vue-router'
5 | import { useTitle as _useTitle } from '@vueuse/core'
6 | import { useI18n, useLocale } from '@pkg/locale'
7 |
8 | /**
9 | * Listening to page changes and dynamically changing site titles
10 | */
11 | export const useTitle = (
12 | title: string,
13 | preventHandler: (
14 | route: RouteLocationNormalizedLoaded,
15 | ) => Promise | boolean,
16 | ) => {
17 | const { t } = useI18n()
18 | const { currentRoute } = useRouter()
19 |
20 | const pageTitle = _useTitle()
21 | const { getLocale } = useLocale()
22 |
23 | watch(
24 | [() => currentRoute.value.path, () => getLocale.value],
25 | async () => {
26 | const route = unref(currentRoute)
27 |
28 | if (!preventHandler(route)) {
29 | return
30 | }
31 |
32 | const tTitle = t(route?.meta?.title as string)
33 | pageTitle.value = tTitle ? ` ${tTitle} - ${title} ` : `${title}`
34 | },
35 | { immediate: true },
36 | )
37 | }
38 |
--------------------------------------------------------------------------------
/packages/use/src/use-window-resize.ts:
--------------------------------------------------------------------------------
1 | import { tryOnMounted, tryOnUnmounted } from '@pkg/utils'
2 | import { useDebounceFn } from '@vueuse/core'
3 |
4 | interface WindowSizeOptions {
5 | once?: boolean
6 | immediate?: boolean
7 | listenerOptions?: AddEventListenerOptions | boolean
8 | }
9 |
10 | export const useWindowResize = (
11 | fn: AnyFunction,
12 | wait = 150,
13 | options?: WindowSizeOptions,
14 | ) => {
15 | let handler = () => {
16 | fn()
17 | }
18 | const handleSize = useDebounceFn(handler, wait)
19 | handler = handleSize
20 |
21 | const start = () => {
22 | if (options && options.immediate) {
23 | handler()
24 | }
25 | window.addEventListener('resize', handler)
26 | }
27 |
28 | const stop = () => {
29 | window.removeEventListener('resize', handler)
30 | }
31 |
32 | tryOnMounted(() => {
33 | start()
34 | })
35 |
36 | tryOnUnmounted(() => {
37 | stop()
38 | })
39 | return [start, stop]
40 | }
41 |
--------------------------------------------------------------------------------
/packages/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './src'
2 | export * from './bem'
3 |
4 | export {
5 | cloneDeep,
6 | sortBy,
7 | omit,
8 | upperFirst,
9 | uniq,
10 | uniqBy,
11 | pick,
12 | merge,
13 | clone,
14 | set,
15 | has,
16 | get,
17 | fromPairs,
18 | difference,
19 | intersection,
20 | } from 'lodash-es'
21 |
--------------------------------------------------------------------------------
/packages/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@pkg/utils",
3 | "version": "3.0.0-alpha.4",
4 | "main": "index.ts",
5 | "module": "index.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo"
9 | },
10 | "dependencies": {
11 | "@pkg/setting": "workspace:*",
12 | "@vue/runtime-core": "^3.2.31",
13 | "@vue/shared": "^3.2.31",
14 | "@vueuse/core": "^8.1.2",
15 | "@vueuse/shared": "^8.1.2",
16 | "dayjs": "^1.11.0",
17 | "lodash-es": "^4.17.21"
18 | },
19 | "devDependencies": {
20 | "@types/lodash-es": "^4.17.6"
21 | },
22 | "optionalDependencies": {
23 | "vue": "^3.2.31"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/utils/src/config.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Get the configuration file variable name
3 | * @param env
4 | */
5 | export const getAppConfigFileName = (env: Record) => {
6 | return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
7 | .toUpperCase()
8 | .replace(/\s/g, '')
9 | }
10 |
--------------------------------------------------------------------------------
/packages/utils/src/date.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Independent time operation tool to facilitate subsequent switch to dayjs
3 | */
4 | import type { ConfigType } from 'dayjs'
5 | import dayjs from 'dayjs'
6 | import utc from 'dayjs/plugin/utc'
7 | import timezone from 'dayjs/plugin/timezone'
8 | import { isString } from '@vue/shared'
9 | const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
10 | const DATE_FORMAT = 'YYYY-MM-DD'
11 | dayjs.extend(utc)
12 | dayjs.extend(timezone)
13 | export const dateUtil = dayjs
14 |
15 | export const formatToDateTime = (
16 | date: ConfigType,
17 | format = DATE_TIME_FORMAT,
18 | ): string => {
19 | return dateUtil(date).format(format)
20 | }
21 | const UTC_DATE_FORMAT_PREFIX = 'utc|'
22 | export const formatToDate = (
23 | date: ConfigType,
24 | format = DATE_FORMAT,
25 | ): string => {
26 | if (isString(format) && format.startsWith(UTC_DATE_FORMAT_PREFIX)) {
27 | const dateFormat = format.replace(UTC_DATE_FORMAT_PREFIX, '')
28 | // return dateUtil(date).tz(dayjs.tz.guess()).format(dateFormat)
29 | return dateUtil(date).tz("Asia/Shanghai").format(dateFormat)
30 | }
31 | return dateUtil(date).format(format)
32 | }
33 |
--------------------------------------------------------------------------------
/packages/utils/src/deep-merge.ts:
--------------------------------------------------------------------------------
1 | import { isObject } from './is'
2 |
3 | export const deepMerge = (src: any = {}, target: any = {}): T => {
4 | let key: string
5 | for (key in target) {
6 | src[key] = isObject(src[key])
7 | ? deepMerge(src[key], target[key])
8 | : (src[key] = target[key])
9 | }
10 | return src
11 | }
12 |
--------------------------------------------------------------------------------
/packages/utils/src/helper/index.ts:
--------------------------------------------------------------------------------
1 | export * from './slot'
2 | export * from './tree'
3 | export * from './route'
4 |
--------------------------------------------------------------------------------
/packages/utils/src/helper/route.ts:
--------------------------------------------------------------------------------
1 | import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'
2 |
3 | export const getRawRoute = (
4 | route: RouteLocationNormalized,
5 | ): RouteLocationNormalized => {
6 | if (!route) {
7 | return route
8 | }
9 | const { matched, ...opt } = route
10 | return {
11 | ...opt,
12 | matched: (matched
13 | ? matched.map((item) => ({
14 | meta: item.meta,
15 | name: item.name,
16 | path: item.path,
17 | }))
18 | : undefined) as RouteRecordNormalized[],
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/utils/src/helper/slot.ts:
--------------------------------------------------------------------------------
1 | import type { Slots } from 'vue'
2 | import { isFunction } from '../is'
3 |
4 | /**
5 | * @description: Get slot to prevent empty error
6 | */
7 | export const getSlot = (slots: Slots, slot = 'default', data?: any) => {
8 | if (!slots || !Reflect.has(slots, slot)) {
9 | return null
10 | }
11 | if (!isFunction(slots[slot])) {
12 | console.error(`${slot} is not a function!`)
13 | return null
14 | }
15 | const slotFn = slots[slot]
16 | if (!slotFn) return null
17 | return slotFn(data)
18 | }
19 |
20 | /**
21 | * extends slots
22 | * @param slots
23 | * @param excludeKeys
24 | */
25 | export const extendSlots = (slots: Slots, excludeKeys: string[] = []) => {
26 | const slotKeys = Object.keys(slots)
27 | const ret: any = {}
28 | slotKeys.map((key) => {
29 | if (excludeKeys.includes(key)) {
30 | return null
31 | }
32 | ret[key] = () => getSlot(slots, key)
33 | })
34 | return ret
35 | }
36 |
--------------------------------------------------------------------------------
/packages/utils/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './is'
2 | export * from './mitt'
3 | export * from './uuid'
4 | export * from './config'
5 | export * from './log'
6 | export * from './date'
7 | export * from './deep-merge'
8 | export * from './util'
9 | export * from './file'
10 | export * from './helper'
11 | export * from './event'
12 | export * from './dom'
13 | export * from './lifecycle'
14 | export * from './color'
15 | export * from './with-install'
16 |
--------------------------------------------------------------------------------
/packages/utils/src/is.ts:
--------------------------------------------------------------------------------
1 | import { isUndefined, isNull } from 'lodash-es'
2 | export { NOOP, isFunction, isString, isArray, isMap } from '@vue/shared'
3 |
4 | export { isClient, isWindow } from '@vueuse/core'
5 |
6 | export {
7 | isNull,
8 | isEmpty,
9 | isNumber,
10 | isBoolean,
11 | isEqual,
12 | isUndefined,
13 | upperFirst,
14 | } from 'lodash-es'
15 |
16 | export const is = (val: unknown, type: string) => {
17 | return toString.call(val) === `[object ${type}]`
18 | }
19 |
20 | export const isUrl = (path: string): boolean => {
21 | const reg =
22 | /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/
23 | return reg.test(path)
24 | }
25 |
26 | export const isDefined = (val?: T): val is T => !isUndefined(val)
27 |
28 | export const isNullOrUndefined = (val?: T): val is T =>
29 | isUndefined(val) || isNull(val)
30 |
31 | export const isObject = (val: any): val is Record =>
32 | val !== null && is(val, 'Object')
33 |
--------------------------------------------------------------------------------
/packages/utils/src/lifecycle.ts:
--------------------------------------------------------------------------------
1 | import { nextTick, onMounted, onActivated } from 'vue'
2 |
3 | export const onMountedOrActivated = (hook: AnyFunction) => {
4 | let mounted: boolean
5 |
6 | onMounted(() => {
7 | hook()
8 | nextTick(() => {
9 | mounted = true
10 | })
11 | })
12 |
13 | onActivated(() => {
14 | if (mounted) {
15 | hook()
16 | }
17 | })
18 | }
19 |
20 | export { tryOnUnmounted, tryOnMounted } from '@vueuse/core'
21 |
--------------------------------------------------------------------------------
/packages/utils/src/log.ts:
--------------------------------------------------------------------------------
1 | export const warn = (message: string) => {
2 | console.warn(`[admin warn]:${message}`)
3 | }
4 |
5 | export const error = (message: string): never => {
6 | throw new Error(`[admin error]:${message}`)
7 | }
8 |
--------------------------------------------------------------------------------
/packages/utils/src/uuid.ts:
--------------------------------------------------------------------------------
1 | const hexList: string[] = []
2 | let unique = 0
3 |
4 | for (let i = 0; i <= 15; i++) {
5 | hexList[i] = i.toString(16)
6 | }
7 |
8 | export const buildUUID = (): string => {
9 | let uuid = ''
10 | for (let i = 1; i <= 36; i++) {
11 | if (i === 9 || i === 14 || i === 19 || i === 24) {
12 | uuid += '-'
13 | } else if (i === 15) {
14 | uuid += 4
15 | } else if (i === 20) {
16 | uuid += hexList[(Math.random() * 4) | 8]
17 | } else {
18 | uuid += hexList[(Math.random() * 16) | 0]
19 | }
20 | }
21 | return uuid.replace(/-/g, '')
22 | }
23 |
24 | export const buildShortUUID = (prefix = ''): string => {
25 | const time = Date.now()
26 | const random = Math.floor(Math.random() * 1000000000)
27 | unique++
28 | return prefix + '_' + random + unique + String(time)
29 | }
30 |
--------------------------------------------------------------------------------
/packages/utils/src/with-install.ts:
--------------------------------------------------------------------------------
1 | import { NOOP } from '@vue/shared'
2 |
3 | export const withInstall = >(
4 | main: T,
5 | extra?: E,
6 | ) => {
7 | ;(main as SFCWithInstall).install = (app): void => {
8 | for (const comp of [main, ...Object.values(extra ?? {})]) {
9 | app.component(comp.name, comp)
10 | }
11 | }
12 |
13 | if (extra) {
14 | for (const [key, comp] of Object.entries(extra)) {
15 | ;(main as any)[key] = comp
16 | }
17 | }
18 | return main as SFCWithInstall & E
19 | }
20 |
21 | export const withInstallFunction = (fn: T, name: string) => {
22 | ;(fn as SFCWithInstall).install = (app) => {
23 | app.config.globalProperties[name] = fn
24 | }
25 |
26 | return fn as SFCWithInstall
27 | }
28 |
29 | export const withNoopInstall = (component: T) => {
30 | ;(component as SFCWithInstall).install = NOOP
31 |
32 | return component as SFCWithInstall
33 | }
34 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'packages/*'
3 | - 'packages/components/*'
4 | - 'apps/*'
5 | - 'configs/*'
6 | - 'scripts'
7 |
--------------------------------------------------------------------------------
/scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scripts",
3 | "private": true,
4 | "bin": {},
5 | "scripts": {
6 | "clean": "pnpm rimraf node_modules && pnpm rimraf dist && pnpm rimraf .turbo",
7 | "dev": "pnpm esno ./src/dev.ts",
8 | "build": "pnpm esno ./src/build.ts"
9 | },
10 | "devDependencies": {
11 | "@types/prompts": "^2.4.0",
12 | "execa": "^6.1.0",
13 | "prompts": "^2.4.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/scripts/src/build.ts:
--------------------------------------------------------------------------------
1 | import { run } from './helper'
2 |
3 | run('build')
4 |
--------------------------------------------------------------------------------
/scripts/src/dev.ts:
--------------------------------------------------------------------------------
1 | import { run } from './helper'
2 |
3 | run('dev')
4 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turborepo.org/schema.json",
3 | "pipeline": {
4 | "build": {
5 | "outputs": ["dist/**"],
6 | "dependsOn": ["^build"]
7 | },
8 | "clean": {
9 | "dependsOn": ["^clean"]
10 | },
11 | "test": {
12 | "dependsOn": ["^test"],
13 | "outputs": []
14 | },
15 | "dev": {
16 | "cache": false
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import type { AliasOptions } from 'vite'
3 | import { defineConfig } from 'vite'
4 | // import { resolve } from 'path'
5 |
6 | // const _resolve = (p: string) => resolve(__dirname, p)
7 |
8 | const alias: AliasOptions = {}
9 |
10 | export default defineConfig({
11 | // test: {
12 | // environment: 'jsdom',
13 | // deps: {
14 | // inline: ['@vue', '@vueuse', 'vue-demi'],
15 | // },
16 | // },
17 | resolve: {
18 | alias,
19 | },
20 | })
21 |
--------------------------------------------------------------------------------
/问题梳理.md:
--------------------------------------------------------------------------------
1 | # 问题梳理
2 |
3 | ## 2022年4月2日
4 |
5 | OrchardCore 的性能问题
6 | 如果开启了ContentField_SQLIndex, 由于存在大量数据更新时需要为多个字段创建索引数据
7 | 算上 全局文档表,会将所有字段都作为索引行
8 |
9 | 比如:如果要批量更新100条数据,相关类型包含10个字段
10 |
11 | 那么,索引行的数量就是100 * 11 = 1100 条插入语句
12 |
13 | 社区讨论的结果是更倾向于为每个类型创建独立的索引表
14 | 既然要一个类型对应一张表,那么OrchardCore 的意义何在?
15 |
16 | 如果基于Abp-Vnext 自己做一个灵活的管理系统需要哪些工作?
17 |
18 | 1. 商业授权问题:VNext版本使用的是 LGPL 授权,只要不修改官方发布的dll,就可以不开源
19 | 2. 动态类型问题:可以参考OC自己做动态类型设计,但是需要自己实现一个类型管理器
20 | 3. 工作流:可以尝试使用 `elsa-core`
21 |
22 | ## 基于Abp的动态化设计
23 |
24 | ### 类型管理系统
25 | #### 类型管理器
26 | - 类型管理器:管理类型的创建,类型的查询,类型的更新,类型的删除
27 | - 类型事件钩子
28 | - 可复用类型: 对应OC的 Part
29 | - 内容事件钩子
30 | - 内容验证
31 | - 字段验证
32 | - 结构管理器
33 | ### 工作流系统
34 |
35 |
36 |
--------------------------------------------------------------------------------