├── .editorconfig ├── .env ├── .env.development ├── .env.production ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .gitpod.yml ├── .prettierignore ├── .stylelintignore ├── .yarnclean ├── Dockerfile ├── LICENSE ├── README.md ├── build ├── config │ └── themeConfig.ts ├── constant.ts ├── generate │ ├── generateModifyVars.ts │ └── icon │ │ └── index.ts ├── getConfigFileName.ts ├── script │ ├── buildConf.ts │ └── postBuild.ts ├── utils.ts └── vite │ ├── plugin │ ├── compress.ts │ ├── html.ts │ ├── imagemin.ts │ ├── index.ts │ ├── mock.ts │ ├── qiankunMicro.ts │ ├── styleImport.ts │ ├── svgSprite.ts │ ├── theme.ts │ └── visualizer.ts │ └── proxy.ts ├── commitlint.config.js ├── index.html ├── jest.config.mjs ├── mock ├── _createProductionServer.ts ├── _util.ts ├── demo │ ├── account.ts │ ├── select-demo.ts │ ├── system.ts │ ├── table-demo.ts │ └── tree-demo.ts └── sys │ ├── menu.ts │ └── user.ts ├── npm ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── prettier.config.js ├── public ├── favicon.ico ├── logo.png └── resource │ ├── img │ └── logo.png │ ├── js │ └── iconfont.js │ ├── logo.png │ └── tinymce │ ├── langs │ ├── en.js │ └── zh_CN.js │ └── skins │ └── ui │ ├── jeecg │ ├── content.css │ ├── content.inline.css │ ├── content.inline.min.css │ ├── content.min.css │ ├── content.mobile.css │ ├── content.mobile.min.css │ ├── fonts │ │ └── tinymce-mobile.woff │ ├── skin.css │ ├── skin.min.css │ ├── skin.mobile.css │ └── skin.mobile.min.css │ ├── 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 ├── selfsigned.crt ├── selfsigned.key ├── src ├── App.vue ├── api │ ├── common │ │ └── api.ts │ ├── demo │ │ ├── account.ts │ │ ├── error.ts │ │ ├── model │ │ │ ├── accountModel.ts │ │ │ ├── optionsModel.ts │ │ │ ├── systemModel.ts │ │ │ └── tableModel.ts │ │ ├── select.ts │ │ ├── system.ts │ │ ├── table.ts │ │ └── tree.ts │ ├── model │ │ └── baseModel.ts │ └── sys │ │ ├── menu.ts │ │ ├── model │ │ ├── menuModel.ts │ │ ├── uploadModel.ts │ │ └── userModel.ts │ │ ├── upload.ts │ │ └── user.ts ├── 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 │ │ ├── js │ │ │ └── iconfont.js │ │ ├── lock.svg │ │ ├── moon.svg │ │ ├── reload-01.svg │ │ ├── sun.svg │ │ ├── test.svg │ │ ├── total-sales.svg │ │ ├── transaction.svg │ │ └── visit-count.svg │ ├── images │ │ ├── ai │ │ │ ├── aiflow.png │ │ │ └── avatar.jpg │ │ ├── checkcode.png │ │ ├── cms_bpm.png │ │ ├── cms_oa.png │ │ ├── daiban.png │ │ ├── demo.png │ │ ├── department.png │ │ ├── drag_cover.png │ │ ├── duban.png │ │ ├── guaz.png │ │ ├── header.jpg │ │ ├── link.png │ │ ├── logo.png │ │ ├── nodata.png │ │ ├── panel_cover.png │ │ ├── pdf4.jpg │ │ ├── people.png │ │ ├── placeholderImage.png │ │ ├── process_no_form.png │ │ ├── setting.png │ │ ├── template_cover.jpg │ │ ├── wallet.png │ │ └── zaiban.png │ ├── less │ │ └── JAreaLinkage.less │ ├── loginmini │ │ ├── icon │ │ │ ├── icon-code.png │ │ │ ├── icon-eye-g.png │ │ │ ├── icon-eye-k.png │ │ │ ├── icon-line-msg.png │ │ │ ├── icon-line-pad.png │ │ │ ├── icon-line-tel.png │ │ │ ├── icon-line-user.png │ │ │ ├── icon-password.png │ │ │ ├── icon-success.png │ │ │ ├── icon-user.png │ │ │ ├── icon_dow.png │ │ │ ├── jeecg_ad.png │ │ │ ├── jeecg_ad_text.png │ │ │ ├── jeecg_bg.png │ │ │ ├── jeecg_logo.png │ │ │ └── logo.png │ │ └── style │ │ │ ├── base.less │ │ │ └── home.less │ └── svg │ │ ├── fileType │ │ ├── excel.svg │ │ ├── image.png │ │ ├── other.svg │ │ ├── pdf.svg │ │ ├── txt.svg │ │ └── word.svg │ │ ├── illustration.svg │ │ ├── login-bg-dark.svg │ │ ├── login-bg.svg │ │ ├── login-box-bg.svg │ │ ├── net-error.svg │ │ ├── no-data.svg │ │ └── preview │ │ ├── p-rotate.svg │ │ ├── resume.svg │ │ ├── scale.svg │ │ ├── unrotate.svg │ │ └── unscale.svg ├── components │ ├── 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 │ ├── Authority │ │ ├── index.ts │ │ └── src │ │ │ └── Authority.vue │ ├── Basic │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicArrow.vue │ │ │ ├── BasicHelp.vue │ │ │ └── BasicTitle.vue │ ├── Button │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicButton.vue │ │ │ ├── JUploadButton.vue │ │ │ ├── PopConfirmButton.vue │ │ │ └── props.ts │ ├── CardList │ │ ├── index.ts │ │ └── src │ │ │ ├── CardList.vue │ │ │ └── data.ts │ ├── ClickOutSide │ │ ├── index.ts │ │ └── src │ │ │ └── ClickOutSide.vue │ ├── CodeEditor │ │ ├── index.ts │ │ └── src │ │ │ ├── CodeEditor.vue │ │ │ ├── codemirror │ │ │ ├── CodeMirror.vue │ │ │ ├── codeMirror.ts │ │ │ └── codemirror.css │ │ │ └── typing.ts │ ├── Container │ │ ├── index.ts │ │ └── src │ │ │ ├── LazyContainer.vue │ │ │ ├── ScrollContainer.vue │ │ │ ├── collapse │ │ │ ├── CollapseContainer.vue │ │ │ └── CollapseHeader.vue │ │ │ └── typing.ts │ ├── ContextMenu │ │ ├── index.ts │ │ └── src │ │ │ ├── ContextMenu.vue │ │ │ ├── createContextMenu.ts │ │ │ └── typing.ts │ ├── CountDown │ │ ├── index.ts │ │ └── src │ │ │ ├── CountButton.vue │ │ │ ├── CountdownInput.vue │ │ │ └── useCountdown.ts │ ├── CountTo │ │ ├── index.ts │ │ └── src │ │ │ └── CountTo.vue │ ├── Cropper │ │ ├── index.ts │ │ └── src │ │ │ ├── CopperModal.vue │ │ │ ├── Cropper.vue │ │ │ ├── CropperAvatar.vue │ │ │ └── typing.ts │ ├── Dag │ │ ├── DagGraph.api.ts │ │ ├── DagGraph.vue │ │ ├── mock.ts │ │ ├── nodes │ │ │ ├── DynamicNode.vue │ │ │ ├── EndNode.vue │ │ │ └── StartNode.vue │ │ └── types.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 │ │ │ ├── ApiRadioGroup.vue │ │ │ ├── ApiSelect.vue │ │ │ ├── ApiTreeSelect.vue │ │ │ ├── FormAction.vue │ │ │ ├── FormItem.vue │ │ │ ├── Middleware.vue │ │ │ └── RadioButtonGroup.vue │ │ │ ├── container │ │ │ └── JFormContainer.vue │ │ │ ├── helper.ts │ │ │ ├── hooks │ │ │ ├── useAdvanced.ts │ │ │ ├── useAutoFocus.ts │ │ │ ├── useComponentRegister.ts │ │ │ ├── useForm.ts │ │ │ ├── useFormContext.ts │ │ │ ├── useFormEvents.ts │ │ │ ├── useFormValues.ts │ │ │ └── useLabelWidth.ts │ │ │ ├── jeecg │ │ │ ├── components │ │ │ │ ├── JAddInput.vue │ │ │ │ ├── JAreaLinkage.vue │ │ │ │ ├── JAreaSelect.vue │ │ │ │ ├── JCategorySelect.vue │ │ │ │ ├── JCheckbox.vue │ │ │ │ ├── JCodeEditor.vue │ │ │ │ ├── JDictSelectTag.vue │ │ │ │ ├── JEasyCron │ │ │ │ │ ├── EasyCronInner.vue │ │ │ │ │ ├── EasyCronInput.vue │ │ │ │ │ ├── EasyCronModal.vue │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── easy.cron.data.ts │ │ │ │ │ ├── easy.cron.inner.less │ │ │ │ │ ├── easy.cron.input.less │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── tabs │ │ │ │ │ │ ├── DayUI.vue │ │ │ │ │ │ ├── HourUI.vue │ │ │ │ │ │ ├── MinuteUI.vue │ │ │ │ │ │ ├── MonthUI.vue │ │ │ │ │ │ ├── SecondUI.vue │ │ │ │ │ │ ├── WeekUI.vue │ │ │ │ │ │ ├── YearUI.vue │ │ │ │ │ │ └── useTabMixin.ts │ │ │ │ │ └── validator.ts │ │ │ │ ├── JEditor.vue │ │ │ │ ├── JEllipsis.vue │ │ │ │ ├── JFormContainer.vue │ │ │ │ ├── JImageUpload.vue │ │ │ │ ├── JImportModal.vue │ │ │ │ ├── JInput.vue │ │ │ │ ├── JInputPop.vue │ │ │ │ ├── JInputSelect.vue │ │ │ │ ├── JMarkdownEditor.vue │ │ │ │ ├── JPopup.vue │ │ │ │ ├── JPopupDict.vue │ │ │ │ ├── JRangeDate.vue │ │ │ │ ├── JRangeNumber.vue │ │ │ │ ├── JRangeTime.vue │ │ │ │ ├── JSearchEngineSearch.vue │ │ │ │ ├── JSearchSelect.vue │ │ │ │ ├── JSelectDept.vue │ │ │ │ ├── JSelectInput.vue │ │ │ │ ├── JSelectMultiple.vue │ │ │ │ ├── JSelectPosition.vue │ │ │ │ ├── JSelectRole.vue │ │ │ │ ├── JSelectUser.vue │ │ │ │ ├── JSelectUserByDept.vue │ │ │ │ ├── JSwitch.vue │ │ │ │ ├── JTreeDict.vue │ │ │ │ ├── JTreeSelect.vue │ │ │ │ ├── JUpload │ │ │ │ │ ├── JUpload.vue │ │ │ │ │ ├── JUploadModal.vue │ │ │ │ │ ├── components │ │ │ │ │ │ └── UploadItemActions.vue │ │ │ │ │ ├── index.ts │ │ │ │ │ └── upload.data.ts │ │ │ │ ├── base │ │ │ │ │ ├── JSelectBiz.vue │ │ │ │ │ └── JTreeBiz.vue │ │ │ │ ├── modal │ │ │ │ │ ├── DeptSelectModal.vue │ │ │ │ │ ├── JPopupOnlReportModal.vue │ │ │ │ │ ├── PositionSelectModal.vue │ │ │ │ │ ├── RoleSelectModal.vue │ │ │ │ │ ├── UserSelectByDepModal.vue │ │ │ │ │ └── UserSelectModal.vue │ │ │ │ ├── positionSelect │ │ │ │ │ └── PositionSelectModal.vue │ │ │ │ ├── roleSelect │ │ │ │ │ ├── RoleSelectInput.vue │ │ │ │ │ └── RoleSelectModal.vue │ │ │ │ └── userSelect │ │ │ │ │ ├── SelectedUserItem.vue │ │ │ │ │ ├── UserList.vue │ │ │ │ │ ├── UserListAndDepart.vue │ │ │ │ │ ├── UserListAndRole.vue │ │ │ │ │ ├── UserSelectModal.vue │ │ │ │ │ ├── index.vue │ │ │ │ │ └── useUserSelect.ts │ │ │ ├── hooks │ │ │ │ ├── useCodeHinting.ts │ │ │ │ ├── useSelectBiz.ts │ │ │ │ └── useTreeBiz.ts │ │ │ └── props │ │ │ │ └── props.ts │ │ │ ├── props.ts │ │ │ ├── types │ │ │ ├── form.ts │ │ │ ├── formItem.ts │ │ │ ├── hooks.ts │ │ │ └── index.ts │ │ │ └── utils │ │ │ ├── Area.ts │ │ │ ├── GroupRequest.ts │ │ │ ├── areaDataUtil.js │ │ │ └── formUtils.ts │ ├── Icon │ │ ├── data │ │ │ └── icons.data.ts │ │ ├── index.ts │ │ └── src │ │ │ ├── Icon.vue │ │ │ ├── IconList.vue │ │ │ ├── IconPicker.vue │ │ │ └── SvgIcon.vue │ ├── InFilter │ │ ├── CascaderPcaInFilter.vue │ │ ├── DatePickerInFilter.vue │ │ └── index.ts │ ├── JVxeCustom │ │ ├── index.ts │ │ └── src │ │ │ ├── components │ │ │ ├── JVxeDepartSelectCell.vue │ │ │ ├── JVxeFileCell.vue │ │ │ ├── JVxeImageCell.vue │ │ │ ├── JVxePcaCell.vue │ │ │ ├── JVxePopupCell.vue │ │ │ ├── JVxeSelectDictSearchCell.ts │ │ │ └── JVxeUserSelectCell.vue │ │ │ └── hooks │ │ │ └── useFileCell.ts │ ├── Loading │ │ ├── index.ts │ │ └── src │ │ │ ├── Loading.vue │ │ │ ├── createLoading.ts │ │ │ ├── typing.ts │ │ │ └── useLoading.ts │ ├── Markdown │ │ ├── index.ts │ │ └── src │ │ │ ├── Markdown.vue │ │ │ ├── MarkdownViewer.vue │ │ │ └── typing.ts │ ├── Menu │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicMenu.vue │ │ │ ├── components │ │ │ ├── BasicMenuItem.vue │ │ │ ├── BasicSubMenuItem.vue │ │ │ └── MenuItemContent.vue │ │ │ ├── index.less │ │ │ ├── props.ts │ │ │ ├── types.ts │ │ │ ├── useBasicMenuContext.ts │ │ │ └── useOpenKeys.ts │ ├── Modal │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicModal.vue │ │ │ ├── JModal │ │ │ └── JModal.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 │ │ ├── injectionKey.ts │ │ └── src │ │ │ ├── PageFooter.vue │ │ │ └── PageWrapper.vue │ ├── Preview │ │ ├── index.ts │ │ └── src │ │ │ ├── Functional.vue │ │ │ ├── Preview.vue │ │ │ ├── functional.ts │ │ │ └── typing.ts │ ├── Qrcode │ │ ├── index.ts │ │ └── src │ │ │ ├── Qrcode.vue │ │ │ ├── drawCanvas.ts │ │ │ ├── drawLogo.ts │ │ │ ├── qrcodePlus.ts │ │ │ ├── toCanvas.ts │ │ │ └── typing.ts │ ├── Scrollbar │ │ ├── index.ts │ │ └── src │ │ │ ├── Scrollbar.vue │ │ │ ├── bar.ts │ │ │ ├── types.d.ts │ │ │ └── util.ts │ ├── SimpleMenu │ │ ├── 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 │ ├── StrengthMeter │ │ ├── index.ts │ │ └── src │ │ │ └── StrengthMeter.vue │ ├── Table │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicTable.vue │ │ │ ├── componentMap.ts │ │ │ ├── components │ │ │ ├── CustomSelectHeader.vue │ │ │ ├── EditTableHeaderIcon.vue │ │ │ ├── ExpandIcon.tsx │ │ │ ├── HeaderCell.vue │ │ │ ├── TableAction.vue │ │ │ ├── TableFooter.vue │ │ │ ├── TableHeader.vue │ │ │ ├── TableImg.vue │ │ │ ├── TableSummary.tsx │ │ │ ├── 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 │ │ │ ├── useColumnsCache.ts │ │ │ ├── useCustomRow.ts │ │ │ ├── useCustomSelection.tsx │ │ │ ├── useDataSource.ts │ │ │ ├── useLoading.ts │ │ │ ├── usePagination.tsx │ │ │ ├── useRowSelection.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 │ ├── Time │ │ ├── index.ts │ │ └── src │ │ │ └── Time.vue │ ├── Tinymce │ │ ├── index.ts │ │ └── src │ │ │ ├── Editor.vue │ │ │ ├── ImgUpload.vue │ │ │ ├── ProcessMask.vue │ │ │ ├── helper.ts │ │ │ └── tinymce.ts │ ├── Transition │ │ ├── index.ts │ │ └── src │ │ │ ├── CollapseTransition.vue │ │ │ ├── CreateTransition.tsx │ │ │ └── ExpandTransition.ts │ ├── Tree │ │ ├── index.ts │ │ ├── src │ │ │ ├── BasicTree.vue │ │ │ ├── TreeIcon.ts │ │ │ ├── components │ │ │ │ └── TreeHeader.vue │ │ │ ├── hooks │ │ │ │ └── useTree.ts │ │ │ └── types │ │ │ │ └── tree.ts │ │ └── style │ │ │ ├── index.less │ │ │ └── index.ts │ ├── Tree_backup │ │ ├── index.ts │ │ └── src │ │ │ ├── Tree.vue │ │ │ ├── TreeHeader.vue │ │ │ ├── TreeIcon.ts │ │ │ ├── props.ts │ │ │ ├── typing.ts │ │ │ └── useTree.ts │ ├── Upload │ │ ├── index.ts │ │ └── src │ │ │ ├── BasicUpload.vue │ │ │ ├── FileList.vue │ │ │ ├── ThumbUrl.vue │ │ │ ├── UploadModal.vue │ │ │ ├── UploadPreviewModal.vue │ │ │ ├── data.tsx │ │ │ ├── helper.ts │ │ │ ├── props.ts │ │ │ ├── typing.ts │ │ │ └── useUpload.ts │ ├── Verify │ │ ├── index.ts │ │ └── src │ │ │ ├── DragVerify.vue │ │ │ ├── ImgRotate.vue │ │ │ ├── props.ts │ │ │ └── typing.ts │ ├── VirtualScroll │ │ ├── index.ts │ │ └── src │ │ │ └── VirtualScroll.vue │ ├── chart │ │ ├── Bar.vue │ │ ├── BarAndLine.vue │ │ ├── BarMulti.vue │ │ ├── ChartCard.vue │ │ ├── Gauge.vue │ │ ├── HeadInfo.vue │ │ ├── LineMulti.vue │ │ ├── Pie.vue │ │ ├── README.md │ │ ├── Radar.vue │ │ ├── RankList.vue │ │ ├── SingleLine.vue │ │ ├── StackBar.vue │ │ └── Trend.vue │ ├── jeecg │ │ ├── AIcon.vue │ │ ├── AiChat │ │ │ ├── assets │ │ │ │ └── avatar.jpg │ │ │ ├── components │ │ │ │ ├── chat.vue │ │ │ │ ├── chatMessage.vue │ │ │ │ ├── chatText.vue │ │ │ │ ├── presetQuestion.vue │ │ │ │ └── slide.vue │ │ │ ├── data.js │ │ │ ├── hooks │ │ │ │ ├── useChat.ts │ │ │ │ └── useScroll.ts │ │ │ ├── index.vue │ │ │ └── style │ │ │ │ ├── github-markdown.less │ │ │ │ ├── highlight.less │ │ │ │ └── style.less │ │ ├── ExcelButton.vue │ │ ├── JPrompt │ │ │ ├── JPrompt.vue │ │ │ ├── hooks │ │ │ │ └── useJPrompt.ts │ │ │ ├── index.ts │ │ │ └── typing.ts │ │ ├── JVxeTable │ │ │ ├── hooks.ts │ │ │ ├── index.ts │ │ │ ├── src │ │ │ │ ├── JVxeTable.ts │ │ │ │ ├── componentMap.ts │ │ │ │ ├── components │ │ │ │ │ ├── JVxeDetailsModal.vue │ │ │ │ │ ├── JVxeReloadEffect.ts │ │ │ │ │ ├── JVxeSubPopover.vue │ │ │ │ │ ├── JVxeToolbar.vue │ │ │ │ │ └── cells │ │ │ │ │ │ ├── JVxeCheckboxCell.vue │ │ │ │ │ │ ├── JVxeDateCell.vue │ │ │ │ │ │ ├── JVxeDragSortCell.vue │ │ │ │ │ │ ├── JVxeInputCell.vue │ │ │ │ │ │ ├── JVxeNormalCell.vue │ │ │ │ │ │ ├── JVxeProgressCell.vue │ │ │ │ │ │ ├── JVxeRadioCell.vue │ │ │ │ │ │ ├── JVxeSelectCell.vue │ │ │ │ │ │ ├── JVxeSlotCell.ts │ │ │ │ │ │ ├── JVxeTextareaCell.vue │ │ │ │ │ │ ├── JVxeTimeCell.vue │ │ │ │ │ │ └── JVxeUploadCell.vue │ │ │ │ ├── hooks │ │ │ │ │ ├── cells │ │ │ │ │ │ └── useJVxeUploadCell.ts │ │ │ │ │ ├── useColumns.ts │ │ │ │ │ ├── useColumnsCache.ts │ │ │ │ │ ├── useData.ts │ │ │ │ │ ├── useDataSource.ts │ │ │ │ │ ├── useDragSort.ts │ │ │ │ │ ├── useFinallyProps.ts │ │ │ │ │ ├── useJVxeComponent.ts │ │ │ │ │ ├── useKeyboardEdit.ts │ │ │ │ │ ├── useLinkage.ts │ │ │ │ │ ├── useMethods.ts │ │ │ │ │ ├── usePagination.ts │ │ │ │ │ ├── useRenderComponents.ts │ │ │ │ │ ├── useToolbar.ts │ │ │ │ │ ├── useValidateRules.ts │ │ │ │ │ └── useWebSocket.ts │ │ │ │ ├── install.ts │ │ │ │ ├── style │ │ │ │ │ ├── index.less │ │ │ │ │ ├── reload-effect.less │ │ │ │ │ ├── vxe.const.less │ │ │ │ │ └── vxe.dark.less │ │ │ │ ├── types │ │ │ │ │ ├── JVxeComponent.ts │ │ │ │ │ ├── JVxeTypes.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── utils │ │ │ │ │ ├── authUtils.ts │ │ │ │ │ ├── enhancedUtils.ts │ │ │ │ │ ├── registerUtils.ts │ │ │ │ │ └── vxeUtils.ts │ │ │ │ └── vxe.data.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── OnLine │ │ │ ├── JPopupOnlReport.vue │ │ │ ├── SearchFormItem.vue │ │ │ ├── hooks │ │ │ │ └── usePopBiz.ts │ │ │ └── types │ │ │ │ └── onlineConfig.ts │ │ ├── UserAvatar.vue │ │ ├── captcha │ │ │ └── CaptchaModal.vue │ │ ├── comment │ │ │ ├── CommentFiles.vue │ │ │ ├── CommentList.vue │ │ │ ├── CommentPanel.vue │ │ │ ├── DataLogList.vue │ │ │ ├── HistoryFileList.vue │ │ │ ├── MyComment.vue │ │ │ ├── UploadChunk.vue │ │ │ ├── comment.less │ │ │ ├── image │ │ │ │ ├── emoji.png │ │ │ │ └── emoji_native.png │ │ │ └── useComment.ts │ │ └── thirdApp │ │ │ ├── JThirdAppButton.vue │ │ │ ├── JThirdAppDropdown.vue │ │ │ └── jThirdApp.api.ts │ └── registerGlobComp.ts ├── design │ ├── ant │ │ ├── btn.less │ │ ├── index.less │ │ ├── input.less │ │ ├── pagination.less │ │ └── table.less │ ├── color.less │ ├── config.less │ ├── entry.css │ ├── index.less │ ├── public.less │ ├── theme.less │ ├── transition │ │ ├── base.less │ │ ├── fade.less │ │ ├── index.less │ │ ├── scale.less │ │ ├── scroll.less │ │ ├── slide.less │ │ └── zoom.less │ └── var │ │ ├── breakpoint.less │ │ ├── easing.less │ │ └── index.less ├── directives │ ├── clickOutside.ts │ ├── index.ts │ ├── loading.ts │ ├── permission.ts │ ├── repeatClick.ts │ └── ripple │ │ ├── index.less │ │ └── index.ts ├── enums │ ├── CompTypeEnum.ts │ ├── DateTypeEnum.ts │ ├── appEnum.ts │ ├── breakpointEnum.ts │ ├── cacheEnum.ts │ ├── exceptionEnum.ts │ ├── httpEnum.ts │ ├── jeecgEnum.ts │ ├── menuEnum.ts │ ├── pageEnum.ts │ ├── roleEnum.ts │ └── sizeEnum.ts ├── hooks │ ├── component │ │ ├── useFormItem.ts │ │ ├── useFormItemSingle.ts │ │ └── usePageContext.ts │ ├── core │ │ ├── onMountedOrActivated.ts │ │ ├── useAttrs.ts │ │ ├── useContext.ts │ │ ├── useLockFn.ts │ │ ├── useRefs.ts │ │ └── useTimeout.ts │ ├── event │ │ ├── useBreakpoint.ts │ │ ├── useEventListener.ts │ │ ├── useIntersectionObserver.ts │ │ ├── useScroll.ts │ │ ├── useScrollTo.ts │ │ └── useWindowSizeFn.ts │ ├── jeecg │ │ └── useAdaptiveWidth.ts │ ├── setting │ │ ├── index.ts │ │ ├── useHeaderSetting.ts │ │ ├── useMenuSetting.ts │ │ ├── useMultipleTabSetting.ts │ │ ├── useRootSetting.ts │ │ └── useTransitionSetting.ts │ ├── system │ │ ├── useAutoAdapt.ts │ │ ├── useJvxeMethods.ts │ │ ├── useListPage.ts │ │ ├── useMethods.ts │ │ └── useThirdLogin.ts │ └── web │ │ ├── useAppInject.ts │ │ ├── useContentHeight.ts │ │ ├── useContextMenu.ts │ │ ├── useCopyModal.ts │ │ ├── useCopyToClipboard.ts │ │ ├── useDesign.ts │ │ ├── useECharts.ts │ │ ├── useFullContent.ts │ │ ├── useI18n.ts │ │ ├── useLockPage.ts │ │ ├── useMessage.ts │ │ ├── useMessage.tsx_backup │ │ ├── usePage.ts │ │ ├── usePagination.ts │ │ ├── usePermission.ts │ │ ├── usePrintJS.ts │ │ ├── useScript.ts │ │ ├── useSortable.ts │ │ ├── useSso.ts │ │ ├── useTabs.ts │ │ ├── useTitle.ts │ │ ├── useWatermark.ts │ │ └── useWebSocket.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 │ │ │ │ ├── LockScreen.vue │ │ │ │ ├── index.ts │ │ │ │ ├── lock │ │ │ │ │ └── LockModal.vue │ │ │ │ ├── notify │ │ │ │ │ ├── NoticeList.vue │ │ │ │ │ ├── data.ts │ │ │ │ │ ├── index.vue │ │ │ │ │ ├── index_old.vue │ │ │ │ │ └── notify.api.ts │ │ │ │ └── user-dropdown │ │ │ │ │ ├── DepartSelect.vue │ │ │ │ │ ├── DropMenuItem.vue │ │ │ │ │ ├── UpdatePassword.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 │ │ │ ├── tabs.theme.card.less │ │ │ ├── tabs.theme.smooth.less │ │ │ ├── types.ts │ │ │ ├── useMultipleTabs.ts │ │ │ └── useTabDropdown.ts │ │ └── trigger │ │ │ ├── HeaderTrigger.vue │ │ │ ├── SiderTrigger.vue │ │ │ └── index.vue │ ├── iframe │ │ ├── index.vue │ │ └── useFrameKeepAlive.ts │ └── page │ │ ├── index.vue │ │ └── transition.ts ├── locales │ ├── helper.ts │ ├── lang │ │ ├── en.ts │ │ ├── en │ │ │ ├── common.ts │ │ │ ├── component.ts │ │ │ ├── layout.ts │ │ │ ├── routes │ │ │ │ ├── basic.ts │ │ │ │ ├── dashboard.ts │ │ │ │ └── demo.ts │ │ │ └── sys.ts │ │ ├── zh-CN │ │ │ ├── common.ts │ │ │ ├── component.ts │ │ │ ├── layout.ts │ │ │ ├── routes │ │ │ │ ├── basic.ts │ │ │ │ ├── dashboard.ts │ │ │ │ └── demo.ts │ │ │ └── sys.ts │ │ └── zh_CN.ts │ ├── setupI18n.ts │ └── useLocale.ts ├── logics │ ├── error-handle │ │ └── index.ts │ ├── initAppConfig.ts │ ├── mitt │ │ └── routeChange.ts │ └── theme │ │ ├── dark.ts │ │ ├── index.ts │ │ ├── updateBackground.ts │ │ ├── updateColorWeak.ts │ │ ├── updateGrayMode.ts │ │ └── util.ts ├── main.ts ├── qiankun │ ├── apps.ts │ ├── index.ts │ ├── micro │ │ ├── index.ts │ │ └── qiankunMicro.ts │ └── state.ts ├── router │ ├── constant.ts │ ├── guard │ │ ├── index.ts │ │ ├── paramMenuGuard.ts │ │ ├── permissionGuard.ts │ │ └── stateGuard.ts │ ├── helper │ │ ├── menuHelper.ts │ │ └── routeHelper.ts │ ├── index.ts │ ├── menus │ │ └── index.ts │ ├── router.ts │ ├── routes │ │ ├── basic.ts │ │ ├── index.ts │ │ ├── mainOut.ts │ │ ├── modules │ │ │ ├── about.ts │ │ │ ├── dashboard.ts │ │ │ └── demo │ │ │ │ ├── charts.ts │ │ │ │ ├── comp.ts │ │ │ │ ├── feat.ts │ │ │ │ ├── iframe.ts │ │ │ │ ├── level.ts │ │ │ │ ├── page.ts │ │ │ │ ├── permission.ts │ │ │ │ ├── setup.ts │ │ │ │ └── system.ts │ │ └── staticRouter.ts │ └── types.ts ├── settings │ ├── componentSetting.ts │ ├── designSetting.ts │ ├── encryptionSetting.ts │ ├── localeSetting.ts │ ├── projectSetting.ts │ ├── registerThirdComp.ts │ └── siteSetting.ts ├── store │ ├── index.ts │ └── modules │ │ ├── app.ts │ │ ├── defIndex.ts │ │ ├── errorLog.ts │ │ ├── locale.ts │ │ ├── lock.ts │ │ ├── multipleTab.ts │ │ ├── permission.ts │ │ └── user.ts ├── utils │ ├── areaData │ │ └── pcaUtils.ts │ ├── auth │ │ └── index.ts │ ├── bem.ts │ ├── browser.js │ ├── cache │ │ ├── index.ts │ │ ├── memory.ts │ │ ├── persistent.ts │ │ └── storageCache.ts │ ├── cipher.ts │ ├── color.ts │ ├── common │ │ ├── compUtils.ts │ │ ├── renderUtils.ts │ │ └── vxeUtils.ts │ ├── dateUtil.ts │ ├── desform │ │ └── customExpression.ts │ ├── dict │ │ ├── DictColors.js │ │ ├── JDictSelectUtil.js │ │ └── index.ts │ ├── domUtils.ts │ ├── encryption │ │ └── signMd5Utils.js │ ├── env.ts │ ├── event │ │ └── index.ts │ ├── factory │ │ └── createAsyncComponent.tsx │ ├── file │ │ ├── base64Conver.ts │ │ └── download.ts │ ├── helper │ │ ├── treeHelper.ts │ │ ├── tsxHelper.tsx │ │ └── validator.ts │ ├── http │ │ └── axios │ │ │ ├── Axios.ts │ │ │ ├── axiosCancel.ts │ │ │ ├── axiosTransform.ts │ │ │ ├── checkStatus.ts │ │ │ ├── helper.ts │ │ │ └── index.ts │ ├── index.ts │ ├── is.ts │ ├── lib │ │ └── echarts.ts │ ├── log.ts │ ├── mitt.ts │ ├── monorepo │ │ ├── dynamicRouter.ts │ │ └── registerPackages.ts │ ├── propTypes.ts │ ├── props.ts │ ├── types.ts │ └── uuid.ts └── views │ ├── asset │ ├── api │ │ ├── AssetApi.api.ts │ │ ├── AssetApi.data.ts │ │ ├── AssetApiList.vue │ │ ├── components │ │ │ ├── AssetApiForm.vue │ │ │ ├── AssetApiLeftTree.vue │ │ │ └── AssetApiModal.vue │ │ └── index.less │ ├── blacklist │ │ ├── BlackList.api.ts │ │ ├── BlackList.data.ts │ │ ├── BlackListList.vue │ │ └── components │ │ │ ├── BlackListForm.vue │ │ │ └── BlackListModal.vue │ ├── common │ │ ├── Common.api.ts │ │ └── components │ │ │ └── SelectAssetLabelModel.vue │ ├── company │ │ ├── AssetCompany.api.ts │ │ ├── AssetCompany.data.ts │ │ ├── AssetCompanyList.vue │ │ └── components │ │ │ ├── AssetCompanyForm.vue │ │ │ └── AssetCompanyModal.vue │ ├── domain │ │ ├── AssetDomain.api.ts │ │ ├── AssetDomain.data.ts │ │ ├── AssetDomainList.vue │ │ └── components │ │ │ ├── AssetDomainForm.vue │ │ │ └── AssetDomainModal.vue │ ├── instance │ │ ├── AssetInstance.api.ts │ │ ├── AssetInstance.data.ts │ │ ├── AssetInstanceList.vue │ │ └── components │ │ │ ├── AssetInstanceForm.vue │ │ │ └── AssetInstanceModal.vue │ ├── ip │ │ ├── AssetIp.api.ts │ │ ├── AssetIp.data.ts │ │ ├── AssetIpList.vue │ │ └── components │ │ │ ├── AssetIpForm.vue │ │ │ └── AssetIpModal.vue │ ├── label │ │ ├── AssetLabel.api.ts │ │ ├── AssetLabel.data.ts │ │ ├── AssetLabelList.vue │ │ └── components │ │ │ ├── AssetLabelForm.vue │ │ │ └── AssetLabelModal.vue │ ├── port │ │ ├── AssetPort.api.ts │ │ ├── AssetPort.data.ts │ │ ├── AssetPortList.vue │ │ └── components │ │ │ ├── AssetPortForm.vue │ │ │ └── AssetPortModal.vue │ ├── project │ │ ├── Project.api.ts │ │ ├── Project.data.ts │ │ ├── ProjectList.vue │ │ └── components │ │ │ ├── ProjectForm.vue │ │ │ └── ProjectModal.vue │ ├── search │ │ ├── AssetSearch.api.ts │ │ ├── AssetSearch.vue │ │ └── components │ │ │ └── AssetImportModal.vue │ ├── search_config │ │ ├── SearchConfig.api.ts │ │ ├── SearchConfig.data.ts │ │ ├── SearchConfig.vue │ │ └── components │ │ │ ├── SearchConfigForm.vue │ │ │ └── SearchConfigModal.vue │ ├── search_keyword │ │ ├── SearchEngineKeyword.api.ts │ │ ├── SearchEngineKeyword.data.ts │ │ ├── SearchEngineKeywordList.vue │ │ └── components │ │ │ ├── SearchEngineKeywordForm.vue │ │ │ └── SearchEngineKeywordModal.vue │ ├── subdomain │ │ ├── AssetSubDomain.api.ts │ │ ├── AssetSubDomain.data.ts │ │ ├── AssetSubDomainList.vue │ │ └── components │ │ │ ├── AssetSubDomainForm.vue │ │ │ └── AssetSubDomainModal.vue │ ├── vul │ │ ├── AssetVul.api.ts │ │ ├── AssetVul.data.ts │ │ ├── AssetVulList.vue │ │ └── components │ │ │ ├── AssetVulForm.vue │ │ │ ├── AssetVulModal.vue │ │ │ └── SelectVulStatusModel.vue │ └── web │ │ ├── AssetWeb.api.ts │ │ ├── AssetWeb.data.ts │ │ ├── AssetWebList.vue │ │ └── components │ │ ├── AssetWebForm.vue │ │ └── AssetWebModal.vue │ ├── client │ ├── client │ │ ├── Client.api.ts │ │ ├── Client.data.ts │ │ ├── ClientList.vue │ │ └── components │ │ │ ├── ClientForm.vue │ │ │ ├── ClientModal.vue │ │ │ └── NodeCard.vue │ ├── config │ │ ├── ClientConfig.api.ts │ │ ├── ClientConfig.data.ts │ │ ├── ClientConfigList.vue │ │ └── components │ │ │ ├── ClientConfigForm.vue │ │ │ └── ClientConfigModal.vue │ └── tools │ │ ├── ClientTools.api.ts │ │ ├── ClientTools.data.ts │ │ ├── ClientToolsList.vue │ │ └── components │ │ ├── ClientToolsForm.vue │ │ └── ClientToolsModal.vue │ ├── dashboard │ ├── Analysis │ │ ├── api.ts │ │ ├── components │ │ │ ├── BdcTabCard.vue │ │ │ ├── ChartGroupCard.vue │ │ │ ├── GrowCard.vue │ │ │ ├── QuickNav.vue │ │ │ ├── SaleTabCard.vue │ │ │ ├── SalesProductPie.vue │ │ │ ├── SiteAnalysis.vue │ │ │ ├── VisitAnalysis.vue │ │ │ ├── VisitAnalysisBar.vue │ │ │ ├── VisitRadar.vue │ │ │ ├── VisitSource.vue │ │ │ └── props.ts │ │ ├── data.ts │ │ ├── homePage │ │ │ ├── IndexAssetCard.vue │ │ │ ├── IndexBdc.vue │ │ │ ├── IndexChart.vue │ │ │ ├── IndexDef.vue │ │ │ ├── IndexFlowCard.vue │ │ │ ├── IndexProjectCard.vue │ │ │ └── IndexTask.vue │ │ └── index.vue │ ├── ai │ │ ├── components │ │ │ └── aide │ │ │ │ ├── images │ │ │ │ └── ai.png │ │ │ │ └── index.vue │ │ └── index.vue │ └── workbench │ │ ├── components │ │ ├── DynamicInfo.vue │ │ ├── ProjectCard.vue │ │ ├── QuickNav.vue │ │ ├── SaleRadar.vue │ │ ├── WorkbenchHeader.vue │ │ └── data.ts │ │ └── index.vue │ ├── demo │ ├── charts │ │ ├── Line.vue │ │ ├── Map.vue │ │ ├── Pie.vue │ │ ├── SaleRadar.vue │ │ ├── china.json │ │ ├── data.ts │ │ └── map │ │ │ ├── Baidu.vue │ │ │ ├── Gaode.vue │ │ │ └── Google.vue │ ├── codemirror │ │ └── index.vue │ ├── comp │ │ ├── button │ │ │ └── index.vue │ │ ├── card-list │ │ │ └── index.vue │ │ ├── count-to │ │ │ └── index.vue │ │ ├── cropper │ │ │ └── index.vue │ │ ├── desc │ │ │ └── index.vue │ │ ├── drawer │ │ │ ├── Drawer1.vue │ │ │ ├── Drawer2.vue │ │ │ ├── Drawer3.vue │ │ │ ├── Drawer4.vue │ │ │ ├── Drawer5.vue │ │ │ └── index.vue │ │ ├── lazy │ │ │ ├── TargetContent.vue │ │ │ ├── Transition.vue │ │ │ └── index.vue │ │ ├── loading │ │ │ └── index.vue │ │ ├── modal │ │ │ ├── Modal1.vue │ │ │ ├── Modal2.vue │ │ │ ├── Modal3.vue │ │ │ ├── Modal4.vue │ │ │ └── index.vue │ │ ├── qrcode │ │ │ └── index.vue │ │ ├── scroll │ │ │ ├── Action.vue │ │ │ ├── VirtualScroll.vue │ │ │ └── index.vue │ │ ├── strength-meter │ │ │ └── index.vue │ │ ├── time │ │ │ └── index.vue │ │ ├── transition │ │ │ └── index.vue │ │ ├── upload │ │ │ └── index.vue │ │ └── verify │ │ │ ├── Rotate.vue │ │ │ └── index.vue │ ├── document │ │ ├── form │ │ │ ├── BasicFiledsLayotForm.vue │ │ │ ├── BasicFixedWidthForm.vue │ │ │ ├── BasicFormAdd.vue │ │ │ ├── BasicFormBtn.vue │ │ │ ├── BasicFormCleanRule.vue │ │ │ ├── BasicFormCompact.vue │ │ │ ├── BasicFormComponent.vue │ │ │ ├── BasicFormConAttribute.vue │ │ │ ├── BasicFormCustom.vue │ │ │ ├── BasicFormCustomComponent.vue │ │ │ ├── BasicFormCustomSlots.vue │ │ │ ├── BasicFormDynamicsRules.vue │ │ │ ├── BasicFormFieldShow.vue │ │ │ ├── BasicFormFieldTip.vue │ │ │ ├── BasicFormFooter.vue │ │ │ ├── BasicFormLayout.vue │ │ │ ├── BasicFormModal.vue │ │ │ ├── BasicFormRander.vue │ │ │ ├── BasicFormRules.vue │ │ │ ├── BasicFormSchemas.vue │ │ │ ├── BasicFormSearch.vue │ │ │ ├── BasicFormSlots.vue │ │ │ ├── BasicFormValue.vue │ │ │ ├── BasicFunctionForm.vue │ │ │ ├── example.data.ts │ │ │ ├── exampleCustom.data.ts │ │ │ ├── index.ts │ │ │ └── tabIndex.vue │ │ └── table │ │ │ ├── AuthColumnDemo.vue │ │ │ ├── BasicTableBorder.vue │ │ │ ├── BasicTableDemo.vue │ │ │ ├── BasicTableDemoAjax.vue │ │ │ ├── CustomerCellDemo.vue │ │ │ ├── EditCellTableDemo.vue │ │ │ ├── EditRowTableDemo.vue │ │ │ ├── ExpandTableDemo.vue │ │ │ ├── ExportTableDemo.vue │ │ │ ├── FixedHeaderColumn.vue │ │ │ ├── InnerTableDemo.vue │ │ │ ├── MergeHeaderDemo.vue │ │ │ ├── MergeTableDemo.vue │ │ │ ├── SelectTableDemo.vue │ │ │ ├── TreeTableDemo.vue │ │ │ ├── index.ts │ │ │ └── tabIndex.vue │ ├── editor │ │ ├── json │ │ │ └── index.vue │ │ ├── markdown │ │ │ ├── Editor.vue │ │ │ └── index.vue │ │ └── tinymce │ │ │ ├── Editor.vue │ │ │ └── index.vue │ ├── feat │ │ ├── breadcrumb │ │ │ ├── ChildrenList.vue │ │ │ ├── ChildrenListDetail.vue │ │ │ ├── FlatList.vue │ │ │ └── FlatListDetail.vue │ │ ├── click-out-side │ │ │ └── index.vue │ │ ├── context-menu │ │ │ └── index.vue │ │ ├── copy │ │ │ └── index.vue │ │ ├── download │ │ │ ├── imgBase64.ts │ │ │ └── index.vue │ │ ├── full-screen │ │ │ └── index.vue │ │ ├── icon │ │ │ └── index.vue │ │ ├── img-preview │ │ │ └── index.vue │ │ ├── menu-params │ │ │ └── index.vue │ │ ├── msg │ │ │ └── index.vue │ │ ├── print │ │ │ └── index.vue │ │ ├── ripple │ │ │ └── index.vue │ │ ├── session-timeout │ │ │ └── index.vue │ │ ├── tab-params │ │ │ └── index.vue │ │ ├── tabs │ │ │ ├── TabDetail.vue │ │ │ └── index.vue │ │ ├── watermark │ │ │ └── index.vue │ │ └── ws │ │ │ └── index.vue │ ├── form │ │ ├── AdvancedForm.vue │ │ ├── AppendForm.vue │ │ ├── CustomerForm.vue │ │ ├── DynamicForm.vue │ │ ├── RefForm.vue │ │ ├── RuleForm.vue │ │ ├── UseForm.vue │ │ └── index.vue │ ├── jeecg │ │ ├── AsyncTreeTable.vue │ │ ├── ImgDragSort.vue │ │ ├── ImgTurnPage.vue │ │ ├── InnerExpandTable.vue │ │ ├── JCodeEditDemo.vue │ │ ├── JEditorDemo.vue │ │ ├── JUploadDemo.vue │ │ ├── JVxeTableDemo │ │ │ ├── JVxeDemo1.vue │ │ │ ├── JVxeDemo2.vue │ │ │ ├── JVxeDemo3.vue │ │ │ ├── JVxeDemo4.vue │ │ │ ├── JVxeDemo5.vue │ │ │ ├── func-demo │ │ │ │ ├── JSBCDemo.vue │ │ │ │ ├── PopupSubTable.vue │ │ │ │ └── SocketReload.vue │ │ │ ├── index.vue │ │ │ └── layout-demo │ │ │ │ ├── ErpTemplate.vue │ │ │ │ ├── Template1.vue │ │ │ │ ├── Template2.vue │ │ │ │ ├── Template3.vue │ │ │ │ ├── Template4.vue │ │ │ │ ├── Template5.vue │ │ │ │ └── index.vue │ │ ├── JeecgComponents.vue │ │ ├── JeecgPdfView.vue │ │ ├── Native │ │ │ ├── less │ │ │ │ └── TableExpand.less │ │ │ └── one │ │ │ │ ├── OneNativeList.vue │ │ │ │ └── components │ │ │ │ ├── OneNativeForm.vue │ │ │ │ └── OneNativeModal.vue │ │ ├── PrintDemo.vue │ │ ├── TableTotal.vue │ │ ├── erplist │ │ │ ├── JeecgOrderCustomerList.vue │ │ │ ├── JeecgOrderTicketList.vue │ │ │ ├── components │ │ │ │ ├── JeecgOrderCustomerModal.vue │ │ │ │ ├── JeecgOrderModal.vue │ │ │ │ └── JeecgOrderTicketModal.vue │ │ │ ├── erplist.api.ts │ │ │ ├── erplist.data.ts │ │ │ └── index.vue │ │ ├── index.vue │ │ ├── jeecgComponents.data.ts │ │ └── model │ │ │ └── JeecgOrderModal.vue │ ├── level │ │ ├── Menu111.vue │ │ ├── Menu12.vue │ │ └── Menu2.vue │ ├── main-out │ │ └── index.vue │ ├── page │ │ ├── account │ │ │ ├── center │ │ │ │ ├── Application.vue │ │ │ │ ├── Article.vue │ │ │ │ ├── Project.vue │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ │ └── setting │ │ │ │ ├── AccountBind.vue │ │ │ │ ├── BaseSetting.vue │ │ │ │ ├── MsgNotify.vue │ │ │ │ ├── SecureSetting.vue │ │ │ │ ├── data.ts │ │ │ │ └── index.vue │ │ ├── desc │ │ │ ├── basic │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ │ └── high │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ ├── form │ │ │ ├── basic │ │ │ │ ├── data.ts │ │ │ │ └── index.vue │ │ │ ├── high │ │ │ │ ├── PersonTable.vue │ │ │ │ ├── data.ts │ │ │ │ └── index.vue │ │ │ └── step │ │ │ │ ├── Step1.vue │ │ │ │ ├── Step2.vue │ │ │ │ ├── Step3.vue │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ ├── list │ │ │ ├── basic │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ │ ├── card │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ │ └── search │ │ │ │ ├── data.tsx │ │ │ │ └── index.vue │ │ └── result │ │ │ ├── fail │ │ │ └── index.vue │ │ │ └── success │ │ │ └── index.vue │ ├── permission │ │ ├── CurrentPermissionMode.vue │ │ ├── back │ │ │ ├── Btn.vue │ │ │ └── index.vue │ │ └── front │ │ │ ├── AuthPageA.vue │ │ │ ├── AuthPageB.vue │ │ │ ├── Btn.vue │ │ │ └── index.vue │ ├── setup │ │ └── index.vue │ ├── system │ │ ├── account │ │ │ ├── AccountDetail.vue │ │ │ ├── AccountModal.vue │ │ │ ├── DeptTree.vue │ │ │ ├── account.data.ts │ │ │ └── index.vue │ │ ├── dept │ │ │ ├── DeptModal.vue │ │ │ ├── dept.data.ts │ │ │ └── index.vue │ │ ├── menu │ │ │ ├── MenuDrawer.vue │ │ │ ├── index.vue │ │ │ └── menu.data.ts │ │ ├── password │ │ │ ├── index.vue │ │ │ └── pwd.data.ts │ │ ├── role │ │ │ ├── RoleDrawer.vue │ │ │ ├── index.vue │ │ │ └── role.data.ts │ │ └── test │ │ │ ├── TestDrawer.vue │ │ │ ├── index.vue │ │ │ └── test.data.ts │ ├── table │ │ ├── AntdTableSummary.vue │ │ ├── AuthColumn.vue │ │ ├── Basic.vue │ │ ├── CustomerCell.vue │ │ ├── EditCellTable.vue │ │ ├── EditRowTable.vue │ │ ├── ExpandTable.vue │ │ ├── FetchTable.vue │ │ ├── FixedColumn.vue │ │ ├── FixedHeight.vue │ │ ├── FooterTable.vue │ │ ├── FormTable.vue │ │ ├── MergeHeader.vue │ │ ├── MultipleHeader.vue │ │ ├── NestedTable.vue │ │ ├── RefTable.vue │ │ ├── TreeTable.vue │ │ ├── UseTable.vue │ │ └── tableData.tsx │ ├── tree │ │ ├── ActionTree.vue │ │ ├── EditTree.vue │ │ ├── data.ts │ │ └── index.vue │ └── vextable │ │ ├── OneToOneModal.vue │ │ ├── VexTableModal.vue │ │ ├── api.ts │ │ ├── data.ts │ │ ├── drawer.vue │ │ ├── form │ │ ├── JeecgOrderCustomerForm.vue │ │ └── JeecgOrderMainForm.vue │ │ ├── index.vue │ │ ├── index2.vue │ │ ├── jvxetable │ │ ├── JVxeTableModal.vue │ │ ├── jvxetable.api.ts │ │ └── jvxetable.data.ts │ │ └── modal.vue │ ├── liteflow │ ├── chains │ │ ├── Chain.api.ts │ │ ├── Chain.data.ts │ │ ├── ChainList.vue │ │ └── components │ │ │ ├── ChainForm.vue │ │ │ └── ChainModal.vue │ ├── client │ │ ├── Client.api.ts │ │ ├── Client.data.ts │ │ ├── ClientList.vue │ │ └── components │ │ │ ├── ClientForm.vue │ │ │ └── ClientModal.vue │ ├── config │ │ ├── ClientConfig.api.ts │ │ ├── ClientConfig.data.ts │ │ ├── ClientConfigList.vue │ │ └── components │ │ │ ├── ClientConfigForm.vue │ │ │ └── ClientConfigModal.vue │ ├── instance │ │ ├── LiteFlowInstance.api.ts │ │ ├── LiteFlowInstance.data.ts │ │ ├── LiteFlowInstanceList.vue │ │ └── components │ │ │ ├── LiteFlowInstanceForm.vue │ │ │ ├── LiteFlowInstanceModal.vue │ │ │ └── LogModal.vue │ ├── scripts │ │ ├── Script.api.ts │ │ ├── Script.data.ts │ │ ├── ScriptList.vue │ │ └── components │ │ │ ├── ScriptForm.vue │ │ │ └── ScriptModal.vue │ └── task │ │ ├── LiteFlowTask.api.ts │ │ ├── LiteFlowTask.data.ts │ │ ├── LiteFlowTaskList.vue │ │ ├── LiteFlowTaskListNoTree.vue │ │ ├── LiteFlowTaskListTree.vue │ │ ├── components │ │ ├── LiteFlowSubTaskModal.vue │ │ ├── LiteFlowTaskForm.vue │ │ ├── LiteFlowTaskModal.vue │ │ └── LogModal.vue │ │ └── subTables │ │ └── LiteFlowSubTaskSubTable.vue │ ├── message │ └── config │ │ ├── MessageConfig.api.ts │ │ ├── MessageConfig.data.ts │ │ ├── MessageConfigList.vue │ │ └── components │ │ ├── MessageConfigForm.vue │ │ └── MessageConfigModal.vue │ ├── monitor │ ├── datalog │ │ ├── DataLogCompareModal.vue │ │ ├── DataLogModal.vue │ │ ├── datalog.api.ts │ │ ├── datalog.data.ts │ │ └── index.vue │ ├── datasource │ │ ├── DataSourceModal.vue │ │ ├── datasource.api.ts │ │ ├── datasource.data.ts │ │ └── index.vue │ ├── disk │ │ ├── DiskInfo.vue │ │ ├── disk.api.ts │ │ └── gauge.vue │ ├── log │ │ ├── index.vue │ │ ├── log.api.ts │ │ └── log.data.ts │ ├── mynews │ │ ├── DetailModal.vue │ │ ├── DynamicNotice.vue │ │ ├── XssWhiteList.ts │ │ ├── index.vue │ │ ├── mynews.api.ts │ │ └── mynews.data.ts │ ├── quartz │ │ ├── QuartzModal.vue │ │ ├── index.vue │ │ ├── quartz.api.ts │ │ └── quartz.data.ts │ ├── redis │ │ ├── index.vue │ │ ├── redis.api.ts │ │ └── redis.data.ts │ ├── route │ │ ├── RouteModal.vue │ │ ├── components │ │ │ └── RouteRecycleBinModal.vue │ │ ├── index.vue │ │ ├── route.api.ts │ │ └── route.data.ts │ ├── server │ │ ├── index.vue │ │ ├── server.api.ts │ │ └── server.data.ts │ └── trace │ │ ├── index.vue │ │ ├── trace.api.ts │ │ └── trace.data.ts │ ├── report │ ├── chartdemo │ │ ├── chartdemo.data.ts │ │ └── index.vue │ └── statisticst │ │ └── index.vue │ ├── super │ ├── airag │ │ ├── aiapp │ │ │ ├── AiApp.api.ts │ │ │ ├── AiApp.data.ts │ │ │ ├── AiAppList.vue │ │ │ ├── chat │ │ │ │ ├── AiChat.vue │ │ │ │ ├── AiChatIcon.vue │ │ │ │ ├── chat.vue │ │ │ │ ├── chatMessage.vue │ │ │ │ ├── chatText.vue │ │ │ │ ├── hooks │ │ │ │ │ ├── useChat.ts │ │ │ │ │ └── useScroll.ts │ │ │ │ ├── js │ │ │ │ │ ├── chat.js │ │ │ │ │ └── useScroll.ts │ │ │ │ ├── presetQuestion.vue │ │ │ │ ├── route │ │ │ │ │ └── register.ts │ │ │ │ ├── slide.vue │ │ │ │ └── style │ │ │ │ │ ├── github-markdown.less │ │ │ │ │ ├── highlight.less │ │ │ │ │ └── style.less │ │ │ ├── components │ │ │ │ ├── AiApp.json │ │ │ │ ├── AiAppAddFlowModal.vue │ │ │ │ ├── AiAppAddKnowledgeModal.vue │ │ │ │ ├── AiAppGeneratedPromptModal.vue │ │ │ │ ├── AiAppModal.vue │ │ │ │ ├── AiAppParamsSettingModal.vue │ │ │ │ ├── AiAppQuickCommandModal.vue │ │ │ │ ├── AiAppSendModal.vue │ │ │ │ └── AiAppSettingModal.vue │ │ │ └── img │ │ │ │ ├── ailogo.png │ │ │ │ ├── iconWebEmbedded.png │ │ │ │ └── webEmbedded.png │ │ ├── aiknowledge │ │ │ ├── AiKnowledgeBase.api.ts │ │ │ ├── AiKnowledgeBase.data.ts │ │ │ ├── AiKnowledgeBaseList.vue │ │ │ ├── components │ │ │ │ ├── AiKnowledgeBaseModal.vue │ │ │ │ ├── AiTextDescModal.vue │ │ │ │ ├── AiragKnowledgeDocListModal.vue │ │ │ │ └── AiragKnowledgeDocTextModal.vue │ │ │ └── icon │ │ │ │ ├── draft.png │ │ │ │ └── knowledge.png │ │ └── aimodel │ │ │ ├── AiModelList.vue │ │ │ ├── components │ │ │ ├── AiModelModal.vue │ │ │ ├── AiModelSeniorForm.vue │ │ │ └── model.json │ │ │ ├── icon │ │ │ ├── OpenAi.png │ │ │ ├── deepspeek.png │ │ │ ├── ollama.png │ │ │ ├── qianfan.png │ │ │ ├── qianwen.png │ │ │ └── zhipuai.png │ │ │ ├── model.api.ts │ │ │ └── model.data.ts │ └── registerSuper.ts │ ├── sys │ ├── about │ │ └── index.vue │ ├── error-log │ │ ├── DetailModal.vue │ │ ├── data.tsx │ │ └── index.vue │ ├── exception │ │ ├── Exception.vue │ │ ├── NetworkErrorException.vue │ │ ├── NotAccessException.vue │ │ ├── NotDataErrorException.vue │ │ ├── ServerErrorException.vue │ │ └── index.ts │ ├── forget-password │ │ ├── step1.vue │ │ ├── step2.vue │ │ └── step3.vue │ ├── iframe │ │ ├── FrameBlank.vue │ │ └── index.vue │ ├── lock │ │ ├── LockPage.vue │ │ ├── index.vue │ │ └── useNow.ts │ ├── login │ │ ├── ForgetPasswordForm.vue │ │ ├── Login.vue │ │ ├── LoginForm.vue │ │ ├── LoginFormTitle.vue │ │ ├── LoginSelect.vue │ │ ├── MobileForm.vue │ │ ├── OAuth2Login.vue │ │ ├── QrCodeForm.vue │ │ ├── RegisterForm.vue │ │ ├── SessionTimeoutLogin.vue │ │ ├── ThirdModal.vue │ │ ├── TokenLoginPage.vue │ │ └── useLogin.ts │ └── redirect │ │ └── index.vue │ └── system │ ├── address │ ├── address.api.ts │ ├── address.data.ts │ ├── components │ │ └── DepartLeftTree.vue │ ├── index.less │ └── index.vue │ ├── appconfig │ ├── ThirdApp.api.ts │ ├── ThirdApp.data.ts │ ├── ThirdAppBindWeEnterpriseModal.vue │ ├── ThirdAppConfigList.vue │ ├── ThirdAppConfigModal.vue │ ├── ThirdAppDingTalkConfigForm.vue │ └── ThirdAppWeEnterpriseConfigForm.vue │ ├── category │ ├── category.api.ts │ ├── category.data.ts │ ├── components │ │ └── CategoryModal.vue │ └── index.vue │ ├── checkRule │ ├── CheckRuleModal.vue │ ├── CheckRuleTestModal.vue │ ├── check.rule.api.ts │ ├── check.rule.data.ts │ └── index.vue │ ├── depart │ ├── components │ │ ├── DepartDataRuleDrawer.vue │ │ ├── DepartFormModal.vue │ │ ├── DepartFormTab.vue │ │ ├── DepartLeftTree.vue │ │ └── DepartRuleTab.vue │ ├── depart.api.ts │ ├── depart.data.ts │ ├── index.less │ └── index.vue │ ├── departUser │ ├── components │ │ ├── DepartBaseInfoTab.vue │ │ ├── DepartRoleAuthDrawer.vue │ │ ├── DepartRoleDataRuleDrawer.vue │ │ ├── DepartRoleInfoTab.vue │ │ ├── DepartRoleModal.vue │ │ ├── DepartRoleUserAuthDrawer.vue │ │ ├── DepartTree.vue │ │ └── DepartUserInfoTab.vue │ ├── depart.user.api.ts │ ├── depart.user.data.ts │ ├── index.less │ └── index.vue │ ├── dict │ ├── components │ │ ├── DictItemList.vue │ │ ├── DictItemModal.vue │ │ ├── DictModal.vue │ │ └── DictRecycleBinModal.vue │ ├── dict.api.ts │ ├── dict.data.ts │ └── index.vue │ ├── examples │ └── demo │ │ ├── DemoModal.vue │ │ ├── demo.api.ts │ │ ├── demo.data.ts │ │ └── index.vue │ ├── fillRule │ ├── FillRuleModal.vue │ ├── fill.rule.api.ts │ ├── fill.rule.data.ts │ └── index.vue │ ├── loginmini │ ├── MiniCodelogin.vue │ ├── MiniForgotpad.vue │ ├── MiniLogin.vue │ ├── MiniRegister.vue │ └── OAuth2Login.vue │ ├── menu │ ├── DataRuleList.vue │ ├── DataRuleModal.vue │ ├── MenuDrawer.vue │ ├── index.vue │ ├── menu.api.ts │ └── menu.data.ts │ ├── message │ ├── components │ │ ├── SysMessageList.vue │ │ ├── SysMessageModal.vue │ │ └── useSysMessage.ts │ ├── manage │ │ ├── ManageDrawer.vue │ │ ├── index.less │ │ ├── index.vue │ │ ├── manage.api.ts │ │ └── manage.data.ts │ └── template │ │ ├── TemplateModal.vue │ │ ├── TemplateTestModal.vue │ │ ├── index.less │ │ ├── index.vue │ │ ├── template.api.ts │ │ └── template.data.ts │ ├── notice │ ├── DetailModal.vue │ ├── NoticeModal.vue │ ├── index.vue │ ├── notice.api.ts │ └── notice.data.ts │ ├── onlineuser │ ├── OnlineUser.api.ts │ ├── OnlineUser.data.ts │ └── OnlineUserList.vue │ ├── ossfile │ ├── index.vue │ ├── ossfile.api.ts │ └── ossfile.data.ts │ ├── position │ ├── PositionModal.vue │ ├── index.vue │ ├── position.api.ts │ └── position.data.ts │ ├── role │ ├── TenantRoleList.vue │ ├── components │ │ ├── RoleDataRuleDrawer.vue │ │ ├── RoleDesc.vue │ │ ├── RoleDrawer.vue │ │ ├── RoleIndexModal.vue │ │ ├── RolePermissionDrawer.vue │ │ ├── RoleUserTable.vue │ │ └── UseSelectModal.vue │ ├── index.vue │ ├── role.api.ts │ └── role.data.ts │ ├── tableWhiteList │ ├── SysTableWhiteList.api.ts │ ├── SysTableWhiteList.data.ts │ ├── SysTableWhiteListList.vue │ └── modules │ │ └── SysTableWhiteListModal.vue │ ├── tenant │ ├── TenantUserList.vue │ ├── components │ │ ├── TenantInviteUserModal.vue │ │ ├── TenantModal.vue │ │ ├── TenantRecycleBinModal.vue │ │ ├── TenantUserDrawer.vue │ │ ├── TenantUserList.vue │ │ └── TenantUserSelectModal.vue │ ├── index.vue │ ├── my │ │ └── MyTenantList.vue │ ├── pack │ │ ├── TenantDefaultPackList.vue │ │ ├── TenantPackList.vue │ │ ├── TenantPackMenuModal.vue │ │ └── TenantPackUserModal.vue │ ├── tenant.api.ts │ └── tenant.data.ts │ ├── user │ ├── PasswordModal.vue │ ├── UserAgentModal.vue │ ├── UserDrawer.vue │ ├── UserQuitAgentModal.vue │ ├── UserQuitModal.vue │ ├── UserRecycleBinModal.vue │ ├── index.vue │ ├── user.api.ts │ ├── user.data.ts │ └── userDetails.vue │ └── usersetting │ ├── AccountSetting.vue │ ├── BaseSetting.vue │ ├── TenantSetting.vue │ ├── UserSetting.api.ts │ ├── UserSetting.data.ts │ ├── UserSetting.vue │ ├── WeChatDingSetting.vue │ ├── commponents │ ├── UserAccountModal.vue │ ├── UserEmailModal.vue │ ├── UserPasswordModal.vue │ └── UserPhoneModal.vue │ └── icons │ ├── anquan1.png │ ├── anquan2.png │ ├── app1.png │ ├── app2.png │ ├── geren1.png │ ├── geren2.png │ ├── zuhu1.png │ └── zuhu2.png ├── stylelint.config.js ├── tests ├── __mocks__ │ ├── fileMock.ts │ ├── styleMock.ts │ └── workerMock.ts ├── server │ ├── README.md │ ├── controller │ │ ├── FileController.ts │ │ └── UserController.ts │ ├── ecosystem.config.js │ ├── index.ts │ ├── nodemon.json │ ├── package.json │ ├── routes.ts │ ├── service │ │ ├── FileService.ts │ │ └── UserService.ts │ ├── tsconfig.json │ └── utils.ts └── test.spec.ts ├── tsconfig.json ├── types ├── axios.d.ts ├── config.d.ts ├── global.d.ts ├── index.d.ts ├── main.d.ts ├── module.d.ts ├── store.d.ts ├── utils.d.ts └── vue-router.d.ts └── vite.config.ts /.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 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # port 2 | VITE_PORT = 3100 3 | 4 | # 网站标题 5 | VITE_GLOB_APP_TITLE = TestNet 资产管理平台 6 | 7 | # 简称,此变量只能是字符/下划线 8 | VITE_GLOB_APP_SHORT_NAME = TestNet 9 | 10 | # 单点登录服务端地址 11 | VITE_GLOB_APP_CAS_BASE_URL=http://cas.test.com:8443/cas 12 | 13 | # 是否开启单点登录 14 | VITE_GLOB_APP_OPEN_SSO = false 15 | 16 | # 开启微前端模式 17 | VITE_GLOB_APP_OPEN_QIANKUN=true 18 | 19 | # 文件预览地址 20 | VITE_GLOB_ONLINE_VIEW_URL=http://fileview.jeecg.com/onlinePreview 21 | 22 | 23 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | # 是否打开mock 2 | VITE_USE_MOCK = true 3 | 4 | # 发布路径 5 | VITE_PUBLIC_PATH = / 6 | 7 | 8 | # 跨域代理,您可以配置多个 ,请注意,没有换行符 9 | VITE_PROXY = [["/jeecgboot","http://localhost:8080/jeecg-boot"],["/upload","http://localhost:3300/upload"]] 10 | 11 | #后台接口全路径地址(必填) 12 | VITE_GLOB_DOMAIN_URL=http://localhost:8080/jeecg-boot 13 | 14 | #后台接口父地址(必填) 15 | VITE_GLOB_API_URL=/jeecgboot 16 | 17 | # 接口前缀 18 | VITE_GLOB_API_URL_PREFIX= 19 | 20 | #微前端qiankun应用,命名必须以VITE_APP_SUB_开头,jeecg-app-1为子应用的项目名称,也是子应用的路由父路径 21 | VITE_APP_SUB_jeecg-app-1 = '//localhost:8092' 22 | 23 | 24 | # 填写后将作为乾坤子应用启动,主应用注册时AppName需保持一致(放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动) 25 | #VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3 26 | # 作为乾坤子应用启动时必填,需与qiankun主应用注册子应用时填写的 entry 保持一致 27 | #VITE_GLOB_QIANKUN_MICRO_APP_ENTRY=//localhost:3001/jeecg-vue3 28 | 29 | # 全局隐藏哪些布局。可选属性:sider,header,multi-tabs;多个用逗号隔开 30 | #VITE_GLOB_HIDE_LAYOUT_TYPES=sider,header,multi-tabs 31 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | # 是否启用mock 2 | VITE_USE_MOCK = false 3 | 4 | # 发布路径 5 | VITE_PUBLIC_PATH = / 6 | 7 | # 是否启用gzip或brotli压缩 8 | # 选项值: gzip | brotli | none 9 | # 如果需要多个可以使用“,”分隔 10 | VITE_BUILD_COMPRESS = 'gzip' 11 | 12 | # 使用压缩时是否删除原始文件,默认为false 13 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false 14 | 15 | #后台接口父地址(必填) 16 | VITE_GLOB_API_URL=/jeecgboot 17 | 18 | #后台接口全路径地址(必填) 19 | VITE_GLOB_DOMAIN_URL=/jeecgboot 20 | 21 | # 接口父路径前缀 22 | VITE_GLOB_API_URL_PREFIX= 23 | 24 | 25 | # 填写后将作为乾坤子应用启动,主应用注册时AppName需保持一致(放开 VITE_GLOB_QIANKUN_MICRO_APP_NAME 参数表示jeecg-vue3将以乾坤子应用模式启动) 26 | #VITE_GLOB_QIANKUN_MICRO_APP_NAME=jeecg-vue3 27 | # 作为乾坤子应用启动时必填,需与qiankun主应用注册子应用时填写的 entry 保持一致 28 | #VITE_GLOB_QIANKUN_MICRO_APP_ENTRY=//qiankun.boot3.jeecg.com/jeecg-vue3 29 | 30 | # 全局隐藏哪些布局。可选属性:sider,header,multi-tabs;多个用逗号隔开 31 | #VITE_GLOB_HIDE_LAYOUT_TYPES=sider,header,multi-tabs 32 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .github 4 | dist 5 | .npmrc 6 | .cache 7 | 8 | tests/server/static 9 | tests/server/static/upload 10 | 11 | .local 12 | # local env files 13 | .env.local 14 | .env.*.local 15 | .eslintcache 16 | 17 | # Log files 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | pnpm-debug.log* 22 | 23 | # Editor directories and files 24 | .idea 25 | .svn 26 | # .vscode 27 | *.suo 28 | *.ntvs* 29 | *.njsproj 30 | *.sln 31 | *.sw? 32 | /os_del.cmd 33 | os_del.cmd 34 | /.vscode/ 35 | /.history/ 36 | /svn clear.bat 37 | pnpm-lock.yaml 38 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | ports: 2 | - port: 3344 3 | onOpen: open-preview 4 | tasks: 5 | - init: yarn 6 | command: yarn dev 7 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | .local 3 | .output.js 4 | /node_modules/** 5 | 6 | **/*.svg 7 | **/*.sh 8 | 9 | /public/* 10 | -------------------------------------------------------------------------------- /.stylelintignore: -------------------------------------------------------------------------------- 1 | /dist/* 2 | /public/* 3 | public/* 4 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | # test directories 2 | __tests__ 3 | test 4 | tests 5 | powered-test 6 | 7 | # asset directories 8 | docs 9 | doc 10 | website 11 | images 12 | assets 13 | 14 | # examples 15 | example 16 | examples 17 | 18 | # code coverage directories 19 | coverage 20 | .nyc_output 21 | 22 | # build scripts 23 | Makefile 24 | Gulpfile.js 25 | Gruntfile.js 26 | 27 | # configs 28 | appveyor.yml 29 | circle.yml 30 | codeship-services.yml 31 | codeship-steps.yml 32 | wercker.yml 33 | .tern-project 34 | .gitattributes 35 | .editorconfig 36 | .*ignore 37 | .eslintrc 38 | .jshintrc 39 | .flowconfig 40 | .documentup.json 41 | .yarn-metadata.json 42 | .travis.yml 43 | 44 | # misc 45 | *.md 46 | 47 | !istanbul-reports/lib/html/assets 48 | !istanbul-api/node_modules/istanbul-reports/lib/html/assets 49 | -------------------------------------------------------------------------------- /build/constant.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The name of the configuration file entered in the production environment 3 | */ 4 | export const GLOB_CONFIG_FILE_NAME = '_app.config.js'; 5 | 6 | export const OUTPUT_DIR = 'dist'; 7 | -------------------------------------------------------------------------------- /build/getConfigFileName.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get the configuration file variable name 3 | * @param env 4 | */ 5 | export const getConfigFileName = (env: Record) => { 6 | return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, ''); 7 | }; 8 | -------------------------------------------------------------------------------- /build/script/postBuild.ts: -------------------------------------------------------------------------------- 1 | // #!/usr/bin/env node 2 | 3 | import { runBuildConfig } from './buildConf'; 4 | import colors from 'picocolors'; 5 | 6 | import pkg from '../../package.json'; 7 | 8 | export const runBuild = async () => { 9 | try { 10 | const argvList = process.argv.splice(2); 11 | 12 | // Generate configuration file 13 | if (!argvList.includes('disabled-config')) { 14 | runBuildConfig(); 15 | } 16 | 17 | console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!'); 18 | } catch (error) { 19 | console.log(colors.red('vite build error:\n' + error)); 20 | process.exit(1); 21 | } 22 | }; 23 | runBuild(); 24 | -------------------------------------------------------------------------------- /build/vite/plugin/imagemin.ts: -------------------------------------------------------------------------------- 1 | // 【图片压缩插件】 2 | // Image resource files used to compress the output of the production environment 3 | // https://github.com/anncwb/vite-plugin-imagemin 4 | import viteImagemin from 'vite-plugin-imagemin'; 5 | 6 | export function configImageminPlugin() { 7 | const plugin = viteImagemin({ 8 | gifsicle: { 9 | optimizationLevel: 7, 10 | interlaced: false, 11 | }, 12 | optipng: { 13 | optimizationLevel: 7, 14 | }, 15 | mozjpeg: { 16 | quality: 20, 17 | }, 18 | pngquant: { 19 | quality: [0.8, 0.9], 20 | speed: 4, 21 | }, 22 | svgo: { 23 | plugins: [ 24 | { 25 | name: 'removeViewBox', 26 | }, 27 | { 28 | name: 'removeEmptyAttrs', 29 | active: false, 30 | }, 31 | ], 32 | }, 33 | }); 34 | return plugin; 35 | } 36 | -------------------------------------------------------------------------------- /build/vite/plugin/mock.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Mock plugin for development and production. 3 | * 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 | injectCode: ` 14 | import { setupProdMockServer } from '../mock/_createProductionServer'; 15 | 16 | setupProdMockServer(); 17 | `, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /build/vite/plugin/qiankunMicro.ts: -------------------------------------------------------------------------------- 1 | import qiankun from 'vite-plugin-qiankun'; 2 | 3 | /** 4 | * 【JEECG作为乾坤子应用】Vite适配乾坤以子应用模式运行 5 | * @param env 6 | */ 7 | export function configQiankunMicroPlugin(env: ViteEnv) { 8 | const {VITE_GLOB_QIANKUN_MICRO_APP_NAME} = env 9 | 10 | return [ 11 | qiankun(VITE_GLOB_QIANKUN_MICRO_APP_NAME!, { 12 | useDevMode: true, 13 | }) 14 | ] 15 | 16 | } 17 | -------------------------------------------------------------------------------- /build/vite/plugin/svgSprite.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Vite Plugin for fast creating SVG sprites. 3 | * https://github.com/anncwb/vite-plugin-svg-icons 4 | */ 5 | 6 | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; 7 | import path from 'path'; 8 | 9 | export function configSvgIconsPlugin(isBuild: boolean) { 10 | const svgIconsPlugin = createSvgIconsPlugin({ 11 | iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], 12 | svgoOptions: isBuild, 13 | // default 14 | symbolId: 'icon-[dir]-[name]', 15 | }); 16 | return svgIconsPlugin; 17 | } 18 | -------------------------------------------------------------------------------- /build/vite/plugin/visualizer.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Package file volume analysis 3 | */ 4 | import visualizer from 'rollup-plugin-visualizer'; 5 | import { isReportMode } from '../../utils'; 6 | 7 | export function configVisualizerConfig() { 8 | if (isReportMode()) { 9 | return visualizer({ 10 | filename: './node_modules/.cache/visualizer/stats.html', 11 | open: true, 12 | gzipSize: true, 13 | brotliSize: true, 14 | }) as Plugin; 15 | } 16 | return []; 17 | } 18 | -------------------------------------------------------------------------------- /build/vite/proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to parse the .env.development proxy configuration 3 | */ 4 | import type { ProxyOptions } from 'vite'; 5 | 6 | type ProxyItem = [string, string]; 7 | 8 | type ProxyList = ProxyItem[]; 9 | 10 | type ProxyTargetList = Record; 11 | 12 | const httpsRE = /^https:\/\//; 13 | 14 | /** 15 | * Generate proxy 16 | * @param list 17 | */ 18 | export function createProxy(list: ProxyList = []) { 19 | const ret: ProxyTargetList = {}; 20 | for (const [prefix, target] of list) { 21 | const isHttps = httpsRE.test(target); 22 | 23 | // https://github.com/http-party/node-http-proxy#options 24 | ret[prefix] = { 25 | target: target, 26 | changeOrigin: true, 27 | ws: true, 28 | rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), 29 | // https is require secure=false 30 | ...(isHttps ? { secure: false } : {}), 31 | }; 32 | } 33 | return ret; 34 | } 35 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ignores: [(commit) => commit.includes('init')], 3 | extends: ['@commitlint/config-conventional'], 4 | rules: { 5 | 'body-leading-blank': [2, 'always'], 6 | 'footer-leading-blank': [1, 'always'], 7 | 'header-max-length': [2, 'always', 108], 8 | 'subject-empty': [2, 'never'], 9 | 'type-empty': [2, 'never'], 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 | 'wip', 26 | 'workflow', 27 | 'types', 28 | 'release', 29 | ], 30 | ], 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /mock/_createProductionServer.ts: -------------------------------------------------------------------------------- 1 | import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'; 2 | 3 | const modules = import.meta.glob('./**/*.ts', { eager: true }); 4 | 5 | const mockModules: any[] = []; 6 | Object.keys(modules).forEach((key) => { 7 | if (key.includes('/_')) { 8 | return; 9 | } 10 | mockModules.push(...(modules as Recordable)[key].default); 11 | }); 12 | 13 | /** 14 | * Used in a production environment. Need to manually import all modules 15 | */ 16 | export function setupProdMockServer() { 17 | createProdMockServer(mockModules); 18 | } 19 | -------------------------------------------------------------------------------- /mock/demo/select-demo.ts: -------------------------------------------------------------------------------- 1 | import { MockMethod } from 'vite-plugin-mock'; 2 | import { resultSuccess, baseUrl } 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 | //根据搜索关键词做一下匹配 10 | let name = `选项${index}`; 11 | if(keyword && name.indexOf(keyword)!=-1){ 12 | result.list.push({ 13 | name: `选项${index}`, 14 | id: `${index}`, 15 | }); 16 | }else if(!keyword){ 17 | result.list.push({ 18 | name: `选项${index}`, 19 | id: `${index}`, 20 | }); 21 | } 22 | } 23 | return result; 24 | }; 25 | 26 | export default [ 27 | { 28 | url: `${baseUrl}/select/getDemoOptions`, 29 | timeout: 1000, 30 | method: 'get', 31 | response: ({ query }) => { 32 | const { keyword,count} = query; 33 | console.log("查询条件:", keyword); 34 | return resultSuccess(demoList(keyword,count)); 35 | }, 36 | }, 37 | ] as MockMethod[]; 38 | -------------------------------------------------------------------------------- /npm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/npm -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | autoprefixer: {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 150, 3 | tabWidth: 2, 4 | useTabs: false, 5 | semi: true, //语句末尾使用分号 6 | vueIndentScriptAndStyle: true, 7 | singleQuote: true, // 使用单引号 8 | quoteProps: 'as-needed', 9 | bracketSpacing: true, 10 | trailingComma: 'es5', 11 | jsxBracketSameLine: false, 12 | jsxSingleQuote: false, 13 | arrowParens: 'always', 14 | insertPragma: false, 15 | requirePragma: false, 16 | proseWrap: 'never', 17 | htmlWhitespaceSensitivity: 'strict', 18 | endOfLine: 'auto', 19 | rangeStart: 0, 20 | }; 21 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/favicon.ico -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/logo.png -------------------------------------------------------------------------------- /public/resource/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/resource/img/logo.png -------------------------------------------------------------------------------- /public/resource/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/resource/logo.png -------------------------------------------------------------------------------- /public/resource/tinymce/skins/ui/jeecg/content.mobile.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 { 8 | /* Note: this file is used inside the content, so isn't part of theming */ 9 | background-color: green; 10 | display: inline-block; 11 | opacity: 0.5; 12 | position: absolute; 13 | } 14 | body { 15 | -webkit-text-size-adjust: none; 16 | } 17 | body img { 18 | /* this is related to the content margin */ 19 | max-width: 96vw; 20 | } 21 | body table img { 22 | max-width: 95%; 23 | } 24 | body { 25 | font-family: sans-serif; 26 | } 27 | table { 28 | border-collapse: collapse; 29 | } 30 | -------------------------------------------------------------------------------- /public/resource/tinymce/skins/ui/jeecg/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{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse} -------------------------------------------------------------------------------- /public/resource/tinymce/skins/ui/jeecg/fonts/tinymce-mobile.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/resource/tinymce/skins/ui/jeecg/fonts/tinymce-mobile.woff -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/public/resource/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff -------------------------------------------------------------------------------- /src/api/demo/account.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | import { GetAccountInfoModel } from './model/accountModel'; 3 | 4 | enum Api { 5 | ACCOUNT_INFO = '/mock/account/getAccountInfo', 6 | SESSION_TIMEOUT = '/mock/user/sessionTimeout', 7 | TOKEN_EXPIRED = '/mock/user/tokenExpired', 8 | } 9 | 10 | // Get personal center-basic settings 11 | 12 | export const accountInfoApi = () => defHttp.get({ url: Api.ACCOUNT_INFO }); 13 | 14 | export const sessionTimeoutApi = () => defHttp.post({ url: Api.SESSION_TIMEOUT }); 15 | 16 | export const tokenExpiredApi = () => defHttp.post({ url: Api.TOKEN_EXPIRED }); 17 | -------------------------------------------------------------------------------- /src/api/demo/error.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 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 = () => defHttp.get({ url: Api.Error }); 13 | -------------------------------------------------------------------------------- /src/api/demo/model/accountModel.ts: -------------------------------------------------------------------------------- 1 | export interface GetAccountInfoModel { 2 | email: string; 3 | name: string; 4 | introduction: string; 5 | phone: string; 6 | address: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/api/demo/model/optionsModel.ts: -------------------------------------------------------------------------------- 1 | import { BasicFetchResult } from '/@/api/model/baseModel'; 2 | 3 | export interface DemoOptionsItem { 4 | label: string; 5 | value: string; 6 | } 7 | 8 | export interface selectParams { 9 | id: number | string; 10 | } 11 | 12 | /** 13 | * @description: Request list return value 14 | */ 15 | export type DemoOptionsGetResultModel = BasicFetchResult; 16 | -------------------------------------------------------------------------------- /src/api/demo/model/tableModel.ts: -------------------------------------------------------------------------------- 1 | import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'; 2 | /** 3 | * @description: Request list interface parameters 4 | */ 5 | export type DemoParams = BasicPageParams; 6 | 7 | export interface DemoListItem { 8 | id: string; 9 | beginTime: string; 10 | endTime: string; 11 | address: string; 12 | name: string; 13 | no: number; 14 | status: number; 15 | } 16 | 17 | /** 18 | * @description: Request list return value 19 | */ 20 | export type DemoListGetResultModel = BasicFetchResult; 21 | -------------------------------------------------------------------------------- /src/api/demo/select.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | import { DemoOptionsItem, selectParams } from './model/optionsModel'; 3 | enum Api { 4 | OPTIONS_LIST = '/mock/select/getDemoOptions', 5 | } 6 | 7 | /** 8 | * @description: Get sample options value 9 | */ 10 | export const optionsListApi = (params?: selectParams) => defHttp.get({ url: Api.OPTIONS_LIST, params }); 11 | -------------------------------------------------------------------------------- /src/api/demo/table.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | import { DemoParams, DemoListGetResultModel } from './model/tableModel'; 3 | 4 | enum Api { 5 | DEMO_LIST = '/mock/table/getDemoList', 6 | } 7 | 8 | /** 9 | * @description: Get sample list value 10 | */ 11 | 12 | export const demoListApi = (params: DemoParams) => 13 | defHttp.get({ 14 | url: Api.DEMO_LIST, 15 | params, 16 | headers: { 17 | ignoreCancelToken: true, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /src/api/demo/tree.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | TREE_OPTIONS_LIST = '/mock/tree/getDemoOptions', 5 | } 6 | 7 | /** 8 | * @description: Get sample options value 9 | */ 10 | export const treeOptionsListApi = (params?: Recordable) => defHttp.get({ url: Api.TREE_OPTIONS_LIST, params }); 11 | -------------------------------------------------------------------------------- /src/api/model/baseModel.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 | 11 | export interface BasicResult { 12 | records: T[]; 13 | total: number; 14 | } 15 | -------------------------------------------------------------------------------- /src/api/sys/model/menuModel.ts: -------------------------------------------------------------------------------- 1 | import type { RouteMeta } from 'vue-router'; 2 | export interface RouteItem { 3 | path: string; 4 | component: any; 5 | meta: RouteMeta; 6 | name?: string; 7 | alias?: string | string[]; 8 | redirect?: string; 9 | caseSensitive?: boolean; 10 | children?: RouteItem[]; 11 | } 12 | 13 | /** 14 | * @description: Get menu return value 15 | */ 16 | export type getMenuListResultModel = RouteItem[]; 17 | -------------------------------------------------------------------------------- /src/api/sys/model/uploadModel.ts: -------------------------------------------------------------------------------- 1 | export interface UploadApiResult { 2 | message: string; 3 | code: number; 4 | url: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/api/sys/upload.ts: -------------------------------------------------------------------------------- 1 | import { UploadApiResult } from './model/uploadModel'; 2 | import { defHttp } from '/@/utils/http/axios'; 3 | import { UploadFileParams } from '/#/axios'; 4 | import { useGlobSetting } from '/@/hooks/setting'; 5 | 6 | const { uploadUrl = '' } = useGlobSetting(); 7 | 8 | /** 9 | * @description: Upload interface 10 | */ 11 | export function uploadApi(params: UploadFileParams, onUploadProgress: (progressEvent: ProgressEvent) => void) { 12 | return defHttp.uploadFile( 13 | { 14 | url: uploadUrl, 15 | onUploadProgress, 16 | }, 17 | params 18 | ); 19 | } 20 | /** 21 | * @description: Upload interface 22 | */ 23 | export function uploadImg(params: UploadFileParams, onUploadProgress: (progressEvent: ProgressEvent) => void) { 24 | return defHttp.uploadFile( 25 | { 26 | url: `${uploadUrl}/sys/common/upload`, 27 | onUploadProgress, 28 | }, 29 | params, 30 | { isReturnResponse: true } 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/assets/images/ai/aiflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/ai/aiflow.png -------------------------------------------------------------------------------- /src/assets/images/ai/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/ai/avatar.jpg -------------------------------------------------------------------------------- /src/assets/images/checkcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/checkcode.png -------------------------------------------------------------------------------- /src/assets/images/cms_bpm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/cms_bpm.png -------------------------------------------------------------------------------- /src/assets/images/cms_oa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/cms_oa.png -------------------------------------------------------------------------------- /src/assets/images/daiban.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/daiban.png -------------------------------------------------------------------------------- /src/assets/images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/demo.png -------------------------------------------------------------------------------- /src/assets/images/department.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/department.png -------------------------------------------------------------------------------- /src/assets/images/drag_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/drag_cover.png -------------------------------------------------------------------------------- /src/assets/images/duban.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/duban.png -------------------------------------------------------------------------------- /src/assets/images/guaz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/guaz.png -------------------------------------------------------------------------------- /src/assets/images/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/header.jpg -------------------------------------------------------------------------------- /src/assets/images/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/link.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/nodata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/nodata.png -------------------------------------------------------------------------------- /src/assets/images/panel_cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/panel_cover.png -------------------------------------------------------------------------------- /src/assets/images/pdf4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/pdf4.jpg -------------------------------------------------------------------------------- /src/assets/images/people.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/people.png -------------------------------------------------------------------------------- /src/assets/images/placeholderImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/placeholderImage.png -------------------------------------------------------------------------------- /src/assets/images/process_no_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/process_no_form.png -------------------------------------------------------------------------------- /src/assets/images/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/setting.png -------------------------------------------------------------------------------- /src/assets/images/template_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/template_cover.jpg -------------------------------------------------------------------------------- /src/assets/images/wallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/wallet.png -------------------------------------------------------------------------------- /src/assets/images/zaiban.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/images/zaiban.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-code.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-eye-g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-eye-g.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-eye-k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-eye-k.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-line-msg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-line-msg.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-line-pad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-line-pad.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-line-tel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-line-tel.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-line-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-line-user.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-password.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-success.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon-user.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/icon_dow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/icon_dow.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/jeecg_ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/jeecg_ad.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/jeecg_ad_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/jeecg_ad_text.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/jeecg_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/jeecg_bg.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/jeecg_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/jeecg_logo.png -------------------------------------------------------------------------------- /src/assets/loginmini/icon/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/loginmini/icon/logo.png -------------------------------------------------------------------------------- /src/assets/svg/fileType/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/assets/svg/fileType/image.png -------------------------------------------------------------------------------- /src/assets/svg/preview/resume.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/assets/svg/preview/unscale.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/Application/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Application/src/search/AppSearchKeyItem.vue: -------------------------------------------------------------------------------- 1 | 6 | 12 | -------------------------------------------------------------------------------- /src/components/Application/src/useAppContext.ts: -------------------------------------------------------------------------------- 1 | import { InjectionKey, Ref } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 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 | -------------------------------------------------------------------------------- /src/components/Authority/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import authority from './src/Authority.vue'; 3 | 4 | export const Authority = withInstall(authority); 5 | -------------------------------------------------------------------------------- /src/components/Basic/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Button/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import type { ExtractPropTypes } from 'vue'; 3 | import button from './src/BasicButton.vue'; 4 | import jUploadButton from './src/JUploadButton.vue'; 5 | import popConfirmButton from './src/PopConfirmButton.vue'; 6 | import { buttonProps } from './src/props'; 7 | 8 | export const Button = withInstall(button); 9 | export const JUploadButton = withInstall(jUploadButton); 10 | export const PopConfirmButton = withInstall(popConfirmButton); 11 | export declare type ButtonProps = Partial>; 12 | -------------------------------------------------------------------------------- /src/components/Button/src/props.ts: -------------------------------------------------------------------------------- 1 | export const buttonProps = { 2 | color: { type: String, validator: (v) => ['error', 'warning', 'success', ''].includes(v) }, 3 | loading: { type: Boolean }, 4 | disabled: { type: Boolean }, 5 | /** 6 | * Text before icon. 7 | */ 8 | preIcon: { type: String }, 9 | /** 10 | * Text after icon. 11 | */ 12 | postIcon: { type: String }, 13 | type: { type: String }, 14 | /** 15 | * preIcon and postIcon icon size. 16 | * @default: 15 17 | */ 18 | iconSize: { type: Number, default: 15 }, 19 | isUpload: { type: Boolean, default: false }, 20 | onClick: { type: Function as PropType<(...args) => any>, default: null }, 21 | }; 22 | -------------------------------------------------------------------------------- /src/components/CardList/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import cardList from './src/CardList.vue'; 3 | 4 | export const CardList = withInstall(cardList); 5 | -------------------------------------------------------------------------------- /src/components/CardList/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 | -------------------------------------------------------------------------------- /src/components/ClickOutSide/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import clickOutSide from './src/ClickOutSide.vue'; 3 | 4 | export const ClickOutSide = withInstall(clickOutSide); 5 | -------------------------------------------------------------------------------- /src/components/ClickOutSide/src/ClickOutSide.vue: -------------------------------------------------------------------------------- 1 | 6 | 20 | -------------------------------------------------------------------------------- /src/components/CodeEditor/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import codeEditor from './src/CodeEditor.vue'; 3 | 4 | export const CodeEditor = withInstall(codeEditor); 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/CodeEditor/src/typing.ts: -------------------------------------------------------------------------------- 1 | export enum MODE { 2 | JSON = 'application/json', 3 | HTML = 'htmlmixed', 4 | JS = 'javascript', 5 | } 6 | -------------------------------------------------------------------------------- /src/components/Container/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import collapseContainer from './src/collapse/CollapseContainer.vue'; 3 | import scrollContainer from './src/ScrollContainer.vue'; 4 | import lazyContainer from './src/LazyContainer.vue'; 5 | 6 | export const CollapseContainer = withInstall(collapseContainer); 7 | export const ScrollContainer = withInstall(scrollContainer); 8 | export const LazyContainer = withInstall(lazyContainer); 9 | 10 | export * from './src/typing'; 11 | -------------------------------------------------------------------------------- /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 = RefType<{ 14 | scrollBottom: () => void; 15 | getScrollWrap: () => Nullable; 16 | scrollTo: (top: number) => void; 17 | }>; 18 | -------------------------------------------------------------------------------- /src/components/ContextMenu/index.ts: -------------------------------------------------------------------------------- 1 | export { createContextMenu, destroyContextMenu } from './src/createContextMenu'; 2 | 3 | export * from './src/typing'; 4 | -------------------------------------------------------------------------------- /src/components/ContextMenu/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?: Fn; 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: Fn; 35 | } 36 | -------------------------------------------------------------------------------- /src/components/CountDown/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/CountTo/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import countTo from './src/CountTo.vue'; 3 | 4 | export const CountTo = withInstall(countTo); 5 | -------------------------------------------------------------------------------- /src/components/Cropper/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/Dag/nodes/EndNode.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /src/components/Dag/nodes/StartNode.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 29 | -------------------------------------------------------------------------------- /src/components/Description/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Description/src/useDescription.ts: -------------------------------------------------------------------------------- 1 | import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing'; 2 | import { ref, getCurrentInstance, unref } from 'vue'; 3 | import { isProdMode } from '/@/utils/env'; 4 | 5 | export function useDescription(props?: Partial): UseDescReturnType { 6 | if (!getCurrentInstance()) { 7 | throw new Error('useDescription() can only be used inside setup() or functional components!'); 8 | } 9 | const desc = ref>(null); 10 | const loaded = ref(false); 11 | 12 | function register(instance: DescInstance) { 13 | if (unref(loaded) && isProdMode()) { 14 | return; 15 | } 16 | desc.value = instance; 17 | props && instance.setDescProps(props); 18 | loaded.value = true; 19 | } 20 | 21 | const methods: DescInstance = { 22 | setDescProps: (descProps: Partial): void => { 23 | unref(desc)?.setDescProps(descProps); 24 | }, 25 | }; 26 | 27 | return [register, methods]; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/Drawer/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Dropdown/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import dropdown from './src/Dropdown.vue'; 3 | 4 | export * from './src/typing'; 5 | export const Dropdown = withInstall(dropdown); 6 | -------------------------------------------------------------------------------- /src/components/Dropdown/src/typing.ts: -------------------------------------------------------------------------------- 1 | export interface DropMenu { 2 | onClick?: Fn; 3 | to?: string; 4 | icon?: string; 5 | event: string | number; 6 | text: string; 7 | disabled?: boolean; 8 | divider?: boolean; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/Form/src/components/Middleware.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 25 | -------------------------------------------------------------------------------- /src/components/Form/src/hooks/useComponentRegister.ts: -------------------------------------------------------------------------------- 1 | import type { ComponentType } from '../types/index'; 2 | import { tryOnUnmounted } from '@vueuse/core'; 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 | -------------------------------------------------------------------------------- /src/components/Form/src/hooks/useFormContext.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 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 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JEasyCron/EasyCronModal.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JEasyCron/easy.cron.data.ts: -------------------------------------------------------------------------------- 1 | import { propTypes } from '/@/utils/propTypes'; 2 | 3 | export const cronEmits = ['change', 'update:value']; 4 | export const cronProps = { 5 | value: propTypes.string.def(''), 6 | disabled: propTypes.bool.def(false), 7 | hideSecond: propTypes.bool.def(false), 8 | hideYear: propTypes.bool.def(false), 9 | remote: propTypes.func, 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JEasyCron/easy.cron.input.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-easy-cron-input'; 3 | 4 | .@{prefix-cls} { 5 | a.open-btn { 6 | cursor: pointer; 7 | 8 | .app-iconify { 9 | position: relative; 10 | top: 1px; 11 | right: 2px; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JEasyCron/index.ts: -------------------------------------------------------------------------------- 1 | // 原开源项目地址:https://gitee.com/toktok/easy-cron 2 | 3 | export { default as JEasyCron } from './EasyCronInput.vue'; 4 | export { default as JEasyCronInner } from './EasyCronInner.vue'; 5 | export { default as JEasyCronModal } from './EasyCronModal.vue'; 6 | export { default as JCronValidator } from './validator'; 7 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JEllipsis.vue: -------------------------------------------------------------------------------- 1 | 9 | 22 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JUpload/index.ts: -------------------------------------------------------------------------------- 1 | export { UploadTypeEnum } from './upload.data'; 2 | export { default as JUpload } from './JUpload.vue'; 3 | export { default as JUploadModal } from './JUploadModal.vue'; 4 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/JUpload/upload.data.ts: -------------------------------------------------------------------------------- 1 | export enum UploadTypeEnum { 2 | all = 'all', 3 | image = 'image', 4 | file = 'file', 5 | } 6 | -------------------------------------------------------------------------------- /src/components/Form/src/jeecg/components/userSelect/useUserSelect.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 用户选择组件支持选择 我自己,以表达式的形式传值 3 | */ 4 | export const mySelfExpress = '#{sys_user_code}'; 5 | 6 | /** 7 | * 用户列表 我自己的数据 8 | */ 9 | export const mySelfData = { 10 | id: mySelfExpress, username: mySelfExpress, realname: '当前用户', avatarIcon: 'idcard-outlined', avatarColor: 'rgb(75 176 79)' 11 | } 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/Form/src/utils/GroupRequest.ts: -------------------------------------------------------------------------------- 1 | import { getAuthCache, setAuthCache } from '/@/utils/auth'; 2 | /** 3 | * 将一个请求分组 4 | * 5 | * @param getPromise 传入一个可以获取到Promise对象的方法 6 | * @param groupId 分组ID,如果不传或者为空则不分组 7 | * @param expire 过期时间,默认 半分钟 8 | */ 9 | export function httpGroupRequest(getPromise, groupId, expire = 1000 * 30) { 10 | if (groupId == null || groupId === '') { 11 | console.log('--------popup----------getFrom DB-------with---no--groupId '); 12 | return getPromise(); 13 | } 14 | 15 | if (getAuthCache(groupId)) { 16 | console.log('---------popup--------getFrom Cache--------groupId = ' + groupId); 17 | return Promise.resolve(getAuthCache(groupId)); 18 | } else { 19 | console.log('--------popup----------getFrom DB---------groupId = ' + groupId); 20 | } 21 | 22 | // 还没有发出请求,就发出第一次的请求 23 | return getPromise().then((res) => { 24 | setAuthCache(groupId, res); 25 | return Promise.resolve(res); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /src/components/Icon/index.ts: -------------------------------------------------------------------------------- 1 | import Icon from './src/Icon.vue'; 2 | import SvgIcon from './src/SvgIcon.vue'; 3 | import IconPicker from './src/IconPicker.vue'; 4 | 5 | export { Icon, IconPicker, SvgIcon }; 6 | 7 | export default Icon; 8 | -------------------------------------------------------------------------------- /src/components/InFilter/CascaderPcaInFilter.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 19 | 20 | 40 | -------------------------------------------------------------------------------- /src/components/InFilter/index.ts: -------------------------------------------------------------------------------- 1 | export {default as DatePickerInFilter} from './DatePickerInFilter.vue'; 2 | export {default as CascaderPcaInFilter} from './CascaderPcaInFilter.vue'; 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/Loading/src/typing.ts: -------------------------------------------------------------------------------- 1 | import { SizeEnum } from '/@/enums/sizeEnum'; 2 | 3 | export interface LoadingProps { 4 | tip: string; 5 | size: SizeEnum; 6 | absolute: boolean; 7 | loading: boolean; 8 | background: string; 9 | theme: 'dark' | 'light'; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/Markdown/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import markDown from './src/Markdown.vue'; 3 | import markDownViewer from './src/MarkdownViewer.vue'; 4 | 5 | export const MarkDown = withInstall(markDown); 6 | export const MarkdownViewer = withInstall(markDownViewer); 7 | export * from './src/typing'; 8 | -------------------------------------------------------------------------------- /src/components/Markdown/src/typing.ts: -------------------------------------------------------------------------------- 1 | import Vditor from 'vditor'; 2 | export interface MarkDownActionType { 3 | getVditor: () => Vditor; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/Menu/index.ts: -------------------------------------------------------------------------------- 1 | import BasicMenu from './src/BasicMenu.vue'; 2 | 3 | export { BasicMenu }; 4 | -------------------------------------------------------------------------------- /src/components/Menu/src/components/BasicMenuItem.vue: -------------------------------------------------------------------------------- 1 | 6 | 21 | -------------------------------------------------------------------------------- /src/components/Menu/src/types.ts: -------------------------------------------------------------------------------- 1 | // import { ComputedRef } from 'vue'; 2 | // import { ThemeEnum } from '/@/enums/appEnum'; 3 | // import { MenuModeEnum } from '/@/enums/menuEnum'; 4 | export interface MenuState { 5 | // 默认选中的列表 6 | defaultSelectedKeys: string[]; 7 | 8 | // 模式 9 | // mode: MenuModeEnum; 10 | 11 | // // 主题 12 | // theme: ComputedRef | ThemeEnum; 13 | 14 | // 缩进 15 | inlineIndent?: number; 16 | 17 | // 展开数组 18 | openKeys: string[]; 19 | 20 | // 当前选中的菜单项 key 数组 21 | selectedKeys: string[]; 22 | 23 | // 收缩状态下展开的数组 24 | collapsedOpenKeys: string[]; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/Menu/src/useBasicMenuContext.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, Ref } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 3 | 4 | export interface BasicRootMenuContextProps { 5 | menuState: any; 6 | } 7 | 8 | const key: InjectionKey = Symbol(); 9 | 10 | export function createBasicRootMenuContext(context: BasicRootMenuContextProps) { 11 | return createContext(context, key, { readonly: false, native: true }); 12 | } 13 | 14 | export function useBasicRootMenuContext() { 15 | return useContext(key); 16 | } 17 | -------------------------------------------------------------------------------- /src/components/Modal/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Modal/src/components/ModalHeader.vue: -------------------------------------------------------------------------------- 1 | 6 | 23 | -------------------------------------------------------------------------------- /src/components/Modal/src/hooks/useModalContext.ts: -------------------------------------------------------------------------------- 1 | import { InjectionKey } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 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 | -------------------------------------------------------------------------------- /src/components/Page/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/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 | -------------------------------------------------------------------------------- /src/components/Page/injectionKey.ts: -------------------------------------------------------------------------------- 1 | export const PageWrapperFixedHeightKey = 'PageWrapperFixedHeight'; 2 | -------------------------------------------------------------------------------- /src/components/Preview/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ImagePreview } from './src/Preview.vue'; 2 | export { createImgPreview } from './src/functional'; 3 | -------------------------------------------------------------------------------- /src/components/Preview/src/functional.ts: -------------------------------------------------------------------------------- 1 | import type { Options, Props } from './typing'; 2 | import ImgPreview from './Functional.vue'; 3 | import { isClient } from '/@/utils/is'; 4 | import { createVNode, render } from 'vue'; 5 | 6 | let instance: ReturnType | null = null; 7 | 8 | export function createImgPreview(options: Options) { 9 | if (!isClient) return; 10 | const propsData: Partial = {}; 11 | const container = document.createElement('div'); 12 | Object.assign(propsData, { show: true, index: 0, scaleStep: 100 }, options); 13 | 14 | instance = createVNode(ImgPreview, propsData); 15 | render(instance, container); 16 | document.body.appendChild(container); 17 | return instance.component?.exposed; 18 | } 19 | -------------------------------------------------------------------------------- /src/components/Qrcode/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import qrCode from './src/Qrcode.vue'; 3 | 4 | export const QrCode = withInstall(qrCode); 5 | export * from './src/typing'; 6 | -------------------------------------------------------------------------------- /src/components/Qrcode/src/qrcodePlus.ts: -------------------------------------------------------------------------------- 1 | // 参考 qr-code-with-logo 进行ts版本修改 2 | import { toCanvas } from './toCanvas'; 3 | export * from './typing'; 4 | export { toCanvas }; 5 | -------------------------------------------------------------------------------- /src/components/Qrcode/src/toCanvas.ts: -------------------------------------------------------------------------------- 1 | import { renderQrCode } from './drawCanvas'; 2 | import { drawLogo } from './drawLogo'; 3 | import { RenderQrCodeParams } from './typing'; 4 | export const toCanvas = (options: RenderQrCodeParams) => { 5 | return renderQrCode(options) 6 | .then(() => { 7 | return options; 8 | }) 9 | .then(drawLogo) as Promise; 10 | }; 11 | -------------------------------------------------------------------------------- /src/components/Qrcode/src/typing.ts: -------------------------------------------------------------------------------- 1 | import type { QRCodeSegment, QRCodeRenderersOptions } from 'qrcode'; 2 | 3 | export type ContentType = string | QRCodeSegment[]; 4 | 5 | export type { QRCodeRenderersOptions }; 6 | 7 | export type LogoType = { 8 | src: string; 9 | logoSize: number; 10 | borderColor: string; 11 | bgColor: string; 12 | borderSize: number; 13 | crossOrigin: string; 14 | borderRadius: number; 15 | logoRadius: number; 16 | }; 17 | 18 | export interface RenderQrCodeParams { 19 | canvas: any; 20 | content: ContentType; 21 | width?: number; 22 | options?: QRCodeRenderersOptions; 23 | logo?: LogoType | string; 24 | image?: HTMLImageElement; 25 | downloadName?: string; 26 | download?: boolean | Fn; 27 | } 28 | 29 | export type ToCanvasFn = (options: RenderQrCodeParams) => Promise; 30 | 31 | export interface QrCodeActionType { 32 | download: (fileName?: string) => void; 33 | } 34 | 35 | export interface QrcodeDoneEventParams { 36 | url: string; 37 | ctx?: CanvasRenderingContext2D | null; 38 | } 39 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/SimpleMenu/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SimpleMenu } from './src/SimpleMenu.vue'; 2 | export { default as SimpleMenuTag } from './src/SimpleMenuTag.vue'; 3 | -------------------------------------------------------------------------------- /src/components/SimpleMenu/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?: Fn; 23 | level: number; 24 | props: Props; 25 | } 26 | -------------------------------------------------------------------------------- /src/components/SimpleMenu/src/components/useSimpleMenuContext.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, Ref } from 'vue'; 2 | import type { Emitter } from '/@/utils/mitt'; 3 | import { createContext, useContext } from '/@/hooks/core/useContext'; 4 | 5 | export interface SimpleRootMenuContextProps { 6 | rootMenuEmitter: Emitter; 7 | activeName: Ref; 8 | } 9 | 10 | const key: InjectionKey = Symbol(); 11 | 12 | export function createSimpleRootMenuContext(context: SimpleRootMenuContextProps) { 13 | return createContext(context, key, { readonly: false, native: true }); 14 | } 15 | 16 | export function useSimpleRootMenuContext() { 17 | return useContext(key); 18 | } 19 | -------------------------------------------------------------------------------- /src/components/SimpleMenu/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface MenuState { 2 | activeName: string; 3 | openNames: string[]; 4 | activeSubMenuNames: string[]; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/StrengthMeter/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import strengthMeter from './src/StrengthMeter.vue'; 3 | 4 | export const StrengthMeter = withInstall(strengthMeter); 5 | -------------------------------------------------------------------------------- /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 | export * from './src/types/table'; 6 | export * from './src/types/pagination'; 7 | export * from './src/types/tableAction'; 8 | export { useTable } from './src/hooks/useTable'; 9 | export type { FormSchema, FormProps } from '/@/components/Form/src/types/form'; 10 | export type { EditRecordRow } from './src/components/editable'; 11 | -------------------------------------------------------------------------------- /src/components/Table/src/components/EditTableHeaderIcon.vue: -------------------------------------------------------------------------------- 1 | 8 | 17 | -------------------------------------------------------------------------------- /src/components/Table/src/components/ExpandIcon.tsx: -------------------------------------------------------------------------------- 1 | import { BasicArrow } from '/@/components/Basic'; 2 | 3 | export default () => { 4 | return (props: Recordable) => { 5 | if (!props.expandable) { 6 | if (props.needIndentSpaced) { 7 | return ; 8 | } else { 9 | return ; 10 | } 11 | } 12 | return ( 13 | { 17 | props.onExpand(props.record, e); 18 | }} 19 | expand={props.expanded} 20 | /> 21 | ); 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /src/components/Table/src/components/editable/helper.ts: -------------------------------------------------------------------------------- 1 | import { ComponentType } from '../../types/componentType'; 2 | import { useI18n } from '/@/hooks/web/useI18n'; 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 | -------------------------------------------------------------------------------- /src/components/Table/src/const.ts: -------------------------------------------------------------------------------- 1 | import componentSetting from '/@/settings/componentSetting'; 2 | 3 | const { table } = componentSetting; 4 | 5 | const { pageSizeOptions, defaultPageSize, defaultSize, fetchSetting, defaultSortFn, defaultFilterFn } = table; 6 | 7 | export const ROW_KEY = 'key'; 8 | 9 | // Optional display number per page; 10 | export const PAGE_SIZE_OPTIONS = pageSizeOptions; 11 | 12 | // Number of items displayed per page 13 | export const PAGE_SIZE = defaultPageSize; 14 | 15 | // Common interface field settings 16 | export const FETCH_SETTING = fetchSetting; 17 | 18 | // Configure general sort function 19 | export const DEFAULT_SORT_FN = defaultSortFn; 20 | 21 | export const DEFAULT_FILTER_FN = defaultFilterFn; 22 | 23 | // Default layout of table cells 24 | export const DEFAULT_ALIGN = 'center'; 25 | // Default Size 26 | export const DEFAULT_SIZE = defaultSize; 27 | 28 | export const INDEX_COLUMN_FLAG = 'INDEX'; 29 | 30 | export const ACTION_COLUMN_FLAG = 'ACTION'; 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/components/Table/src/types/componentType.ts: -------------------------------------------------------------------------------- 1 | export type ComponentType = 'Input' | 'InputNumber' | 'Select' | 'ApiSelect' | 'ApiTreeSelect' | 'Checkbox' | 'Switch' | 'DatePicker' | 'TimePicker'; 2 | -------------------------------------------------------------------------------- /src/components/Time/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils/index'; 2 | import time from './src/Time.vue'; 3 | 4 | export const Time = withInstall(time); 5 | -------------------------------------------------------------------------------- /src/components/Tinymce/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils/index'; 2 | import tinymce from './src/Editor.vue'; 3 | 4 | export const Tinymce = withInstall(tinymce); 5 | -------------------------------------------------------------------------------- /src/components/Tree/index.ts: -------------------------------------------------------------------------------- 1 | import BasicTree from './src/BasicTree.vue'; 2 | import './style'; 3 | 4 | export { BasicTree }; 5 | export type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; 6 | export * from './src/types/tree'; 7 | -------------------------------------------------------------------------------- /src/components/Tree/src/TreeIcon.ts: -------------------------------------------------------------------------------- 1 | import type { VNode, FunctionalComponent } from 'vue'; 2 | 3 | import { h } from 'vue'; 4 | import { isString } from '@vue/shared'; 5 | import { Icon } from '/@/components/Icon'; 6 | 7 | export const TreeIcon: FunctionalComponent = ({ icon }: { icon: VNode | string }) => { 8 | if (!icon) return null; 9 | if (isString(icon)) { 10 | return h(Icon, { icon, class: 'mr-1' }); 11 | } 12 | return Icon; 13 | }; 14 | -------------------------------------------------------------------------------- /src/components/Tree/style/index.ts: -------------------------------------------------------------------------------- 1 | import './index.less'; 2 | -------------------------------------------------------------------------------- /src/components/Tree_backup/index.ts: -------------------------------------------------------------------------------- 1 | import BasicTree from './src/Tree.vue'; 2 | 3 | export { BasicTree }; 4 | export type { ContextMenuItem } from '/@/hooks/web/useContextMenu'; 5 | export * from './src/typing'; 6 | -------------------------------------------------------------------------------- /src/components/Tree_backup/src/TreeIcon.ts: -------------------------------------------------------------------------------- 1 | import type { VNode, FunctionalComponent } from 'vue'; 2 | 3 | import { h } from 'vue'; 4 | import { isString } from '/@/utils/is'; 5 | import { Icon } from '/@/components/Icon'; 6 | 7 | export interface ComponentProps { 8 | icon: VNode | string; 9 | } 10 | 11 | export const TreeIcon: FunctionalComponent = ({ icon }: ComponentProps) => { 12 | if (!icon) return null; 13 | if (isString(icon)) { 14 | return h(Icon, { icon, class: 'mr-1' }); 15 | } 16 | return Icon; 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/Upload/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils'; 2 | import basicUpload from './src/BasicUpload.vue'; 3 | 4 | export const BasicUpload = withInstall(basicUpload); 5 | -------------------------------------------------------------------------------- /src/components/Upload/src/ThumbUrl.vue: -------------------------------------------------------------------------------- 1 | 6 | 19 | 30 | -------------------------------------------------------------------------------- /src/components/Verify/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils/index'; 2 | import basicDragVerify from './src/DragVerify.vue'; 3 | import rotateDragVerify from './src/ImgRotate.vue'; 4 | 5 | export const BasicDragVerify = withInstall(basicDragVerify); 6 | export const RotateDragVerify = withInstall(rotateDragVerify); 7 | export * from './src/typing'; 8 | -------------------------------------------------------------------------------- /src/components/Verify/src/typing.ts: -------------------------------------------------------------------------------- 1 | export interface DragVerifyActionType { 2 | resume: () => void; 3 | } 4 | 5 | export interface PassingData { 6 | isPassing: boolean; 7 | time: number; 8 | } 9 | 10 | export interface MoveData { 11 | event: MouseEvent | TouchEvent; 12 | moveDistance: number; 13 | moveX: number; 14 | } 15 | -------------------------------------------------------------------------------- /src/components/VirtualScroll/index.ts: -------------------------------------------------------------------------------- 1 | import { withInstall } from '/@/utils/index'; 2 | import vScroll from './src/VirtualScroll.vue'; 3 | 4 | export const VScroll = withInstall(vScroll); 5 | -------------------------------------------------------------------------------- /src/components/jeecg/AIcon.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/components/jeecg/AiChat/assets/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/components/jeecg/AiChat/assets/avatar.jpg -------------------------------------------------------------------------------- /src/components/jeecg/AiChat/hooks/useChat.ts: -------------------------------------------------------------------------------- 1 | import { useChatStore } from '@/store' 2 | 3 | export function useChat() { 4 | const chatStore = useChatStore() 5 | 6 | const getChatByUuidAndIndex = (uuid: number, index: number) => { 7 | return chatStore.getChatByUuidAndIndex(uuid, index) 8 | } 9 | 10 | const addChat = (uuid: number, chat: Chat.Chat) => { 11 | chatStore.addChatByUuid(uuid, chat) 12 | } 13 | 14 | const updateChat = (uuid: number, index: number, chat: Chat.Chat) => { 15 | chatStore.updateChatByUuid(uuid, index, chat) 16 | } 17 | 18 | const updateChatSome = (uuid: number, index: number, chat: Partial) => { 19 | chatStore.updateChatSomeByUuid(uuid, index, chat) 20 | } 21 | 22 | return { 23 | addChat, 24 | updateChat, 25 | updateChatSome, 26 | getChatByUuidAndIndex, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/components/jeecg/JPrompt/index.ts: -------------------------------------------------------------------------------- 1 | export { useJPrompt } from './hooks/useJPrompt'; 2 | export { default as JPrompt } from './JPrompt.vue'; 3 | -------------------------------------------------------------------------------- /src/components/jeecg/JPrompt/typing.ts: -------------------------------------------------------------------------------- 1 | import { ModalOptionsPartial } from '/@/hooks/web/useMessage'; 2 | import { RenderCallbackParams, Rule } from '/@/components/Form'; 3 | 4 | export interface JPromptProps extends ModalOptionsPartial { 5 | // 输入框是否必填 6 | required?: boolean; 7 | // 校验 8 | rules?: Rule[]; 9 | // 动态校验 10 | dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[]; 11 | // 占位字符 12 | placeholder?: string; 13 | // 输入框默认值 14 | defaultValue?: string; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/hooks.ts: -------------------------------------------------------------------------------- 1 | export { useJVxeCompProps, useJVxeComponent } from './src/hooks/useJVxeComponent'; 2 | export { useResolveComponent } from './src/hooks/useData'; 3 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/index.ts: -------------------------------------------------------------------------------- 1 | export { default as JVxeTable } from './src/JVxeTable'; 2 | export { registerJVxeTable } from './src/install'; 3 | export { deleteComponent } from './src/componentMap'; 4 | export { registerComponent, registerAsyncComponent, registerASyncComponentReal } from './src/utils/registerUtils'; 5 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/src/hooks/useKeyboardEdit.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * JVxeTable 键盘操作 3 | */ 4 | import type { VxeTablePropTypes } from 'vxe-table'; 5 | import type { JVxeTableProps } from '../types'; 6 | import { computed } from 'vue'; 7 | 8 | /** 9 | * JVxeTable 键盘操作 10 | * 11 | * @param props 12 | */ 13 | export function useKeyboardEdit(props: JVxeTableProps) { 14 | // 是否开启了键盘操作 15 | const enabledKeyboard = computed(() => props.keyboardEdit ?? false); 16 | // 重写 keyboardConfig 17 | const keyboardConfig: VxeTablePropTypes.KeyboardConfig = { 18 | editMethod({ row, column, $table }) { 19 | // 重写默认的覆盖式,改为追加式 20 | $table.setActiveCell(row, column); 21 | return true; 22 | }, 23 | }; 24 | // 键盘操作配置 25 | const keyboardEditConfig = computed(() => { 26 | return { 27 | mouseConfig: { 28 | selected: enabledKeyboard.value, 29 | }, 30 | keyboardConfig, 31 | }; 32 | }); 33 | 34 | return { 35 | keyboardEditConfig, 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/src/style/reload-effect.less: -------------------------------------------------------------------------------- 1 | .j-vxe-reload-effect-box { 2 | &, 3 | .j-vxe-reload-effect-span { 4 | display: inline; 5 | height: 100%; 6 | position: relative; 7 | } 8 | 9 | .j-vxe-reload-effect-span { 10 | &.layer-top { 11 | display: inline-block; 12 | width: 100%; 13 | 14 | position: absolute; 15 | z-index: 2; 16 | background-color: white; 17 | 18 | transform-origin: 0 0; 19 | animation: reload-effect 1.5s forwards; 20 | } 21 | 22 | &.layer-bottom { 23 | z-index: 1; 24 | } 25 | } 26 | 27 | // 定义动画 28 | @keyframes reload-effect { 29 | 0% { 30 | opacity: 1; 31 | transform: rotateX(0); 32 | } 33 | 10% { 34 | opacity: 1; 35 | } 36 | 90% { 37 | opacity: 0; 38 | } 39 | 100% { 40 | opacity: 0; 41 | transform: rotateX(180deg); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/src/style/vxe.const.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-j-vxe-table'; 3 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/src/utils/vxeUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 根据 tagName 获取父级节点 4 | * 5 | * @param dom 一级dom节点 6 | * @param tagName 标签名,不区分大小写 7 | */ 8 | export function getParentNodeByTagName(dom: HTMLElement, tagName: string = 'body'): HTMLElement | null { 9 | if (tagName === 'body') { 10 | return document.body; 11 | } 12 | if (dom.parentElement) { 13 | if (dom.parentElement.tagName.toLowerCase() === tagName.trim().toLowerCase()) { 14 | return dom.parentElement; 15 | } else { 16 | return getParentNodeByTagName(dom.parentElement, tagName); 17 | } 18 | } else { 19 | return null; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/components/jeecg/JVxeTable/types.ts: -------------------------------------------------------------------------------- 1 | import JVxeTable from './src/JVxeTable'; 2 | 3 | export type { JVxeComponent } from './src/types/JVxeComponent'; 4 | export type { JVxeColumn, JVxeLinkageConfig } from './src/types'; 5 | export { JVxeTypes } from './src/types/JVxeTypes'; 6 | export type JVxeTableInstance = InstanceType; 7 | -------------------------------------------------------------------------------- /src/components/jeecg/comment/image/emoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/components/jeecg/comment/image/emoji.png -------------------------------------------------------------------------------- /src/components/jeecg/comment/image/emoji_native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/components/jeecg/comment/image/emoji_native.png -------------------------------------------------------------------------------- /src/design/ant/input.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../color.less'; 2 | 3 | // input 4 | .ant-input { 5 | &-number { 6 | min-width: 110px; 7 | } 8 | } 9 | 10 | .ant-input-affix-wrapper .ant-input-suffix { 11 | right: 9px; 12 | } 13 | 14 | .ant-input-clear-icon { 15 | margin-right: 5px; 16 | } 17 | 18 | .ant-input-affix-wrapper-textarea-with-clear-btn { 19 | padding: 0 !important; 20 | 21 | textarea.ant-input { 22 | padding: 4px; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/design/config.less: -------------------------------------------------------------------------------- 1 | @import (reference) 'color.less'; 2 | @import (reference) 'var/index.less'; 3 | -------------------------------------------------------------------------------- /src/design/transition/base.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 | .expand-transition { 13 | .transition-default(); 14 | } 15 | 16 | .expand-x-transition { 17 | .transition-default(); 18 | } 19 | -------------------------------------------------------------------------------- /src/design/transition/index.less: -------------------------------------------------------------------------------- 1 | @import './base.less'; 2 | @import './fade.less'; 3 | @import './scale.less'; 4 | @import './slide.less'; 5 | @import './scroll.less'; 6 | @import './zoom.less'; 7 | 8 | .collapse-transition { 9 | transition: 0.2s height ease-in-out, 0.2s padding-top ease-in-out, 0.2s padding-bottom ease-in-out; 10 | } 11 | -------------------------------------------------------------------------------- /src/design/transition/scale.less: -------------------------------------------------------------------------------- 1 | .scale-transition { 2 | .transition-default(); 3 | 4 | &-enter-from, 5 | &-leave, 6 | &-leave-to { 7 | opacity: 0; 8 | transform: scale(0); 9 | } 10 | } 11 | 12 | .scale-rotate-transition { 13 | .transition-default(); 14 | 15 | &-enter-from, 16 | &-leave, 17 | &-leave-to { 18 | opacity: 0; 19 | transform: scale(0) rotate(-45deg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/design/transition/slide.less: -------------------------------------------------------------------------------- 1 | .slide-y-transition { 2 | .transition-default(); 3 | 4 | &-enter-from, 5 | &-leave-to { 6 | opacity: 0; 7 | transform: translateY(-15px); 8 | } 9 | } 10 | 11 | .slide-y-reverse-transition { 12 | .transition-default(); 13 | 14 | &-enter-from, 15 | &-leave-to { 16 | opacity: 0; 17 | transform: translateY(15px); 18 | } 19 | } 20 | 21 | .slide-x-transition { 22 | .transition-default(); 23 | 24 | &-enter-from, 25 | &-leave-to { 26 | opacity: 0; 27 | transform: translateX(-15px); 28 | } 29 | } 30 | 31 | .slide-x-reverse-transition { 32 | .transition-default(); 33 | 34 | &-enter-from, 35 | &-leave-to { 36 | opacity: 0; 37 | transform: translateX(15px); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/design/transition/zoom.less: -------------------------------------------------------------------------------- 1 | // zoom-out 2 | .zoom-out-enter-active, 3 | .zoom-out-leave-active { 4 | transition: opacity 0.1 ease-in-out, transform 0.15s ease-out; 5 | } 6 | 7 | .zoom-out-enter-from, 8 | .zoom-out-leave-to { 9 | opacity: 0; 10 | transform: scale(0); 11 | } 12 | 13 | // zoom-fade 14 | .zoom-fade-enter-active, 15 | .zoom-fade-leave-active { 16 | transition: transform 0.2s, opacity 0.3s ease-out; 17 | } 18 | 19 | .zoom-fade-enter-from { 20 | opacity: 0; 21 | transform: scale(0.92); 22 | } 23 | 24 | .zoom-fade-leave-to { 25 | opacity: 0; 26 | transform: scale(1.06); 27 | } 28 | -------------------------------------------------------------------------------- /src/design/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 | -------------------------------------------------------------------------------- /src/design/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 | -------------------------------------------------------------------------------- /src/directives/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Configure and register global directives 3 | */ 4 | import type { App } from 'vue'; 5 | import { setupPermissionDirective } from './permission'; 6 | import { setupLoadingDirective } from './loading'; 7 | 8 | export function setupGlobDirectives(app: App) { 9 | setupPermissionDirective(app); 10 | setupLoadingDirective(app); 11 | } 12 | -------------------------------------------------------------------------------- /src/directives/repeatClick.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Prevent repeated clicks 3 | * @Example v-repeat-click="()=>{}" 4 | */ 5 | import { on, once } from '/@/utils/domUtils'; 6 | import type { Directive, DirectiveBinding } from 'vue'; 7 | 8 | const repeatDirective: Directive = { 9 | beforeMount(el: Element, binding: DirectiveBinding) { 10 | let interval: Nullable = null; 11 | let startTime = 0; 12 | const handler = (): void => binding?.value(); 13 | const clear = (): void => { 14 | if (Date.now() - startTime < 100) { 15 | handler(); 16 | } 17 | interval && clearInterval(interval); 18 | interval = null; 19 | }; 20 | 21 | on(el, 'mousedown', (e: MouseEvent): void => { 22 | if ((e as any).button !== 0) return; 23 | startTime = Date.now(); 24 | once(document as any, 'mouseup', clear); 25 | interval && clearInterval(interval); 26 | interval = setInterval(handler, 100); 27 | }); 28 | }, 29 | }; 30 | 31 | export default repeatDirective; 32 | -------------------------------------------------------------------------------- /src/directives/ripple/index.less: -------------------------------------------------------------------------------- 1 | .ripple-container { 2 | position: absolute; 3 | top: 0; 4 | left: 0; 5 | width: 0; 6 | height: 0; 7 | overflow: hidden; 8 | pointer-events: none; 9 | } 10 | 11 | .ripple-effect { 12 | position: relative; 13 | z-index: 9999; 14 | width: 1px; 15 | height: 1px; 16 | margin-top: 0; 17 | margin-left: 0; 18 | pointer-events: none; 19 | border-radius: 50%; 20 | transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1); 21 | } 22 | -------------------------------------------------------------------------------- /src/enums/CompTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 组件类型 3 | */ 4 | export enum CompTypeEnum { 5 | //单选 6 | Radio = 'radio', 7 | //按钮样式单选 8 | RadioButton = 'radioButton', 9 | //下拉框 10 | Select = 'select', 11 | //列表 12 | List = 'list', 13 | //开关 14 | Switch = 'switch', 15 | //下拉树 16 | SelTree = 'sel_tree', 17 | //分类字典树 18 | CatTree = 'cat_tree', 19 | //下拉搜索 20 | SelSearch = 'search', 21 | //用户现在框 22 | SelUser = 'sel_user', 23 | //复选框 24 | Checkbox = 'checkbox', 25 | //多选列表 26 | ListMulti = 'list_multi', 27 | //区域选择 28 | Pca = 'pca', 29 | Popup = 'popup', 30 | //部门选择 31 | SelDepart = 'sel_depart', 32 | } 33 | -------------------------------------------------------------------------------- /src/enums/DateTypeEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 日期类型 3 | */ 4 | export enum DateTypeEnum { 5 | Date = 'date', 6 | Datetime = 'datetime', 7 | Time = 'time', 8 | } 9 | -------------------------------------------------------------------------------- /src/enums/breakpointEnum.ts: -------------------------------------------------------------------------------- 1 | export enum sizeEnum { 2 | XS = 'XS', 3 | SM = 'SM', 4 | MD = 'MD', 5 | LG = 'LG', 6 | XL = 'XL', 7 | XXL = 'XXL', 8 | } 9 | 10 | export enum screenEnum { 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(sizeEnum.XS, screenEnum.XS); 22 | screenMap.set(sizeEnum.SM, screenEnum.SM); 23 | screenMap.set(sizeEnum.MD, screenEnum.MD); 24 | screenMap.set(sizeEnum.LG, screenEnum.LG); 25 | screenMap.set(sizeEnum.XL, screenEnum.XL); 26 | screenMap.set(sizeEnum.XXL, screenEnum.XXL); 27 | 28 | export { screenMap }; 29 | -------------------------------------------------------------------------------- /src/enums/exceptionEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description: Exception related enumeration 3 | */ 4 | export enum ExceptionEnum { 5 | // page not access 6 | PAGE_NOT_ACCESS = 403, 7 | 8 | // page not found 9 | PAGE_NOT_FOUND = 404, 10 | 11 | // error 12 | ERROR = 500, 13 | 14 | // net work error 15 | NET_WORK_ERROR = 10000, 16 | 17 | // No data on the page. In fact, it is not an exception page 18 | PAGE_NOT_DATA = 10100, 19 | //短信验证码次数太多失败code,用于判断是否打开弹窗 20 | PHONE_SMS_FAIL_CODE = 40002, 21 | } 22 | 23 | export enum ErrorTypeEnum { 24 | VUE = 'vue', 25 | SCRIPT = 'script', 26 | RESOURCE = 'resource', 27 | AJAX = 'ajax', 28 | PROMISE = 'promise', 29 | } 30 | -------------------------------------------------------------------------------- /src/enums/jeecgEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * JInput组件类型 3 | */ 4 | export enum JInputTypeEnum { 5 | //模糊 6 | JINPUT_QUERY_LIKE = 'like', 7 | //非 8 | JINPUT_QUERY_NE = 'ne', 9 | //大于等于 10 | JINPUT_QUERY_GE = 'ge', 11 | //小于等于 12 | JINPUT_QUERY_LE = 'le', 13 | } 14 | 15 | /** 16 | * 面板设计器需要的常量定义 17 | */ 18 | export enum JDragConfigEnum { 19 | //baseURL 20 | DRAG_BASE_URL = 'drag-base-url', 21 | //拖拽缓存前缀 22 | DRAG_CACHE_PREFIX = 'drag-cache:', 23 | } 24 | -------------------------------------------------------------------------------- /src/enums/menuEnum.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 | -------------------------------------------------------------------------------- /src/enums/pageEnum.ts: -------------------------------------------------------------------------------- 1 | export enum PageEnum { 2 | // basic login path 3 | BASE_LOGIN = '/login', 4 | // basic home path 5 | BASE_HOME = '/dashboard/analysis', 6 | // error page path 7 | ERROR_PAGE = '/exception', 8 | // error log page path 9 | ERROR_LOG_PAGE = '/error-log/list', 10 | // auth2登录路由路径 11 | OAUTH2_LOGIN_PAGE_PATH = '/oauth2-app/login', 12 | //文件路由 13 | SYS_FILES_PATH = '/file/share', 14 | // 邮件中的跳转地址 15 | TOKEN_LOGIN = '/tokenLogin' 16 | } 17 | -------------------------------------------------------------------------------- /src/enums/roleEnum.ts: -------------------------------------------------------------------------------- 1 | export enum RoleEnum { 2 | // super admin 3 | SUPER = 'super', 4 | 5 | // tester 6 | TEST = 'test', 7 | } 8 | -------------------------------------------------------------------------------- /src/enums/sizeEnum.ts: -------------------------------------------------------------------------------- 1 | export enum SizeEnum { 2 | DEFAULT = 'default', 3 | SMALL = 'small', 4 | LARGE = 'large', 5 | } 6 | 7 | export enum SizeNumberEnum { 8 | DEFAULT = 48, 9 | SMALL = 16, 10 | LARGE = 64, 11 | } 12 | 13 | export enum ScreenSizeEnum { 14 | XS = 480, 15 | SM = 576, 16 | MD = 768, 17 | LG = 992, 18 | XL = 1200, 19 | } 20 | 21 | export const sizeMap: Map = (() => { 22 | const map = new Map(); 23 | map.set(SizeEnum.DEFAULT, SizeNumberEnum.DEFAULT); 24 | map.set(SizeEnum.SMALL, SizeNumberEnum.SMALL); 25 | map.set(SizeEnum.LARGE, SizeNumberEnum.LARGE); 26 | return map; 27 | })(); 28 | -------------------------------------------------------------------------------- /src/hooks/component/usePageContext.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, ComputedRef, Ref } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 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 | -------------------------------------------------------------------------------- /src/hooks/core/onMountedOrActivated.ts: -------------------------------------------------------------------------------- 1 | import { nextTick, onMounted, onActivated } from 'vue'; 2 | 3 | type HookArgs = { 4 | type: 'mounted' | 'activated'; 5 | } 6 | 7 | export function onMountedOrActivated(hook: Fn) { 8 | let mounted: boolean; 9 | 10 | onMounted(() => { 11 | hook({type: 'mounted'}); 12 | nextTick(() => { 13 | mounted = true; 14 | }); 15 | }); 16 | 17 | onActivated(() => { 18 | if (mounted) { 19 | hook({type: 'activated'}); 20 | } 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /src/hooks/core/useLockFn.ts: -------------------------------------------------------------------------------- 1 | import { ref, unref } from 'vue'; 2 | 3 | export function useLockFn

(fn: (...args: P) => Promise) { 4 | const lockRef = ref(false); 5 | return async function (...args: P) { 6 | if (unref(lockRef)) return; 7 | lockRef.value = true; 8 | try { 9 | const ret = await fn(...args); 10 | lockRef.value = false; 11 | return ret; 12 | } catch (e) { 13 | lockRef.value = false; 14 | throw e; 15 | } 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /src/hooks/core/useRefs.ts: -------------------------------------------------------------------------------- 1 | import type { Ref } from 'vue'; 2 | import { ref, onBeforeUpdate } from 'vue'; 3 | 4 | export function useRefs(): [Ref, (index: number) => (el: HTMLElement) => void] { 5 | const refs = ref([]) as Ref; 6 | 7 | onBeforeUpdate(() => { 8 | refs.value = []; 9 | }); 10 | 11 | const setRefs = (index: number) => (el: HTMLElement) => { 12 | refs.value[index] = el; 13 | }; 14 | 15 | return [refs, setRefs]; 16 | } 17 | -------------------------------------------------------------------------------- /src/hooks/event/useWindowSizeFn.ts: -------------------------------------------------------------------------------- 1 | import { tryOnMounted, tryOnUnmounted } from '@vueuse/core'; 2 | import { useDebounceFn } from '@vueuse/core'; 3 | 4 | interface WindowSizeOptions { 5 | once?: boolean; 6 | immediate?: boolean; 7 | listenerOptions?: AddEventListenerOptions | boolean; 8 | } 9 | 10 | export function useWindowSizeFn(fn: Fn, wait = 150, options?: WindowSizeOptions) { 11 | let handler = () => { 12 | fn(); 13 | }; 14 | const handleSize = useDebounceFn(handler, wait); 15 | handler = handleSize; 16 | 17 | const start = () => { 18 | if (options && options.immediate) { 19 | handler(); 20 | } 21 | window.addEventListener('resize', handler); 22 | }; 23 | 24 | const stop = () => { 25 | window.removeEventListener('resize', handler); 26 | }; 27 | 28 | tryOnMounted(() => { 29 | start(); 30 | }); 31 | 32 | tryOnUnmounted(() => { 33 | stop(); 34 | }); 35 | return [start, stop]; 36 | } 37 | -------------------------------------------------------------------------------- /src/hooks/web/useAppInject.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 | -------------------------------------------------------------------------------- /src/hooks/web/useContextMenu.ts: -------------------------------------------------------------------------------- 1 | import { onUnmounted, getCurrentInstance } from 'vue'; 2 | import { createContextMenu, destroyContextMenu } from '/@/components/ContextMenu'; 3 | import type { ContextMenuItem } from '/@/components/ContextMenu'; 4 | export type { ContextMenuItem }; 5 | export function useContextMenu(authRemove = true) { 6 | if (getCurrentInstance() && authRemove) { 7 | onUnmounted(() => { 8 | destroyContextMenu(); 9 | }); 10 | } 11 | return [createContextMenu, destroyContextMenu]; 12 | } 13 | -------------------------------------------------------------------------------- /src/hooks/web/useDesign.ts: -------------------------------------------------------------------------------- 1 | import { useAppProviderContext } from '/@/components/Application'; 2 | // import { computed } from 'vue'; 3 | // import { lowerFirst } from 'lodash-es'; 4 | export function useDesign(scope: string) { 5 | const values = useAppProviderContext(); 6 | // const $style = cssModule ? useCssModule() : {}; 7 | 8 | // const style: Record = {}; 9 | // if (cssModule) { 10 | // Object.keys($style).forEach((key) => { 11 | // // const moduleCls = $style[key]; 12 | // const k = key.replace(new RegExp(`^${values.prefixCls}-?`, 'ig'), ''); 13 | // style[lowerFirst(k)] = $style[key]; 14 | // }); 15 | // } 16 | return { 17 | // prefixCls: computed(() => `${values.prefixCls}-${scope}`), 18 | prefixCls: `${values.prefixCls}-${scope}`, 19 | prefixVar: values.prefixCls, 20 | // style, 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/hooks/web/useFullContent.ts: -------------------------------------------------------------------------------- 1 | import { computed, unref } from 'vue'; 2 | 3 | import { useAppStore } from '/@/store/modules/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 | -------------------------------------------------------------------------------- /src/hooks/web/usePrintJS.ts: -------------------------------------------------------------------------------- 1 | import { nextTick } from 'vue'; 2 | import $printJS, { Configuration } from 'print-js'; 3 | import Print from 'vue-print-nb-jeecg/src/printarea'; 4 | 5 | /** 6 | * 调用 printJS,如果type = html,就走 printNB 的方法 7 | */ 8 | export function printJS(configuration: Configuration) { 9 | if (configuration?.type === 'html') { 10 | printNb(configuration.printable); 11 | } else { 12 | return $printJS(configuration); 13 | } 14 | } 15 | 16 | /** 调用 printNB 打印 */ 17 | export function printNb(domId) { 18 | if (domId) { 19 | localPrint(domId); 20 | } else { 21 | window.print(); 22 | } 23 | } 24 | 25 | let closeBtn = true; 26 | 27 | function localPrint(domId) { 28 | if (typeof domId === 'string' && !domId.startsWith('#')) { 29 | domId = '#' + domId; 30 | } 31 | nextTick(() => { 32 | if (closeBtn) { 33 | closeBtn = false; 34 | new Print({ 35 | el: domId, 36 | endCallback() { 37 | closeBtn = true; 38 | }, 39 | }); 40 | } 41 | }); 42 | } 43 | -------------------------------------------------------------------------------- /src/hooks/web/useSortable.ts: -------------------------------------------------------------------------------- 1 | import { nextTick, unref } from 'vue'; 2 | import type { Ref } from 'vue'; 3 | import type { Options } from 'sortablejs'; 4 | 5 | export function useSortable(el: HTMLElement | Ref, options?: Options) { 6 | function initSortable() { 7 | nextTick(async () => { 8 | if (!el) return; 9 | 10 | const Sortable = (await import('sortablejs')).default; 11 | Sortable.create(unref(el), { 12 | animation: 500, 13 | delay: 400, 14 | delayOnTouchOnly: true, 15 | ...options, 16 | }); 17 | }); 18 | } 19 | 20 | return { initSortable }; 21 | } 22 | -------------------------------------------------------------------------------- /src/layouts/default/content/useContentContext.ts: -------------------------------------------------------------------------------- 1 | import type { InjectionKey, ComputedRef } from 'vue'; 2 | import { createContext, useContext } from '/@/hooks/core/useContext'; 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 | -------------------------------------------------------------------------------- /src/layouts/default/header/components/index.ts: -------------------------------------------------------------------------------- 1 | import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; 2 | import FullScreen from './FullScreen.vue'; 3 | 4 | export const UserDropDown = createAsyncComponent(() => import('./user-dropdown/index.vue'), { 5 | loading: true, 6 | }); 7 | 8 | export const LayoutBreadcrumb = createAsyncComponent(() => import('./Breadcrumb.vue')); 9 | 10 | export const Notify = createAsyncComponent(() => import('./notify/index.vue')); 11 | 12 | export const ErrorAction = createAsyncComponent(() => import('./ErrorAction.vue')); 13 | 14 | export const LockScreen = createAsyncComponent(() => import('./LockScreen.vue')); 15 | 16 | export { FullScreen }; 17 | -------------------------------------------------------------------------------- /src/layouts/default/header/components/notify/notify.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | listCementByUser = '/sys/annountCement/listByUser', 5 | getUnreadMessageCount = '/sys/annountCement/getUnreadMessageCount', 6 | editCementSend = '/sys/sysAnnouncementSend/editByAnntIdAndUserId', 7 | clearAllUnReadMessage = '/sys/annountCement/clearAllUnReadMessage', 8 | } 9 | 10 | /** 11 | * 获取系统通知消息列表 12 | * @param params 13 | */ 14 | export const listCementByUser = (params?) => defHttp.get({ url: Api.listCementByUser, params }); 15 | 16 | /** 17 | * 获取用户近两个月未读消息数量 18 | * @param params 19 | */ 20 | export const getUnreadMessageCount = (params?) => defHttp.get({ url: Api.getUnreadMessageCount, params }); 21 | 22 | export const editCementSend = (anntId, params?) => defHttp.put({ url: Api.editCementSend, params: { anntId, ...params } }); 23 | 24 | /** 25 | * 清空全部未读消息 26 | */ 27 | export const clearAllUnReadMessage = () => defHttp.post({ url: Api.clearAllUnReadMessage },{ isTransformResponse: false }); 28 | -------------------------------------------------------------------------------- /src/layouts/default/setting/components/index.ts: -------------------------------------------------------------------------------- 1 | import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; 2 | 3 | export const TypePicker = createAsyncComponent(() => import('./TypePicker.vue')); 4 | export const ThemeColorPicker = createAsyncComponent(() => import('./ThemeColorPicker.vue')); 5 | export const SettingFooter = createAsyncComponent(() => import('./SettingFooter.vue')); 6 | export const SwitchItem = createAsyncComponent(() => import('./SwitchItem.vue')); 7 | export const SelectItem = createAsyncComponent(() => import('./SelectItem.vue')); 8 | export const InputNumberItem = createAsyncComponent(() => import('./InputNumberItem.vue')); 9 | -------------------------------------------------------------------------------- /src/layouts/default/setting/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/layouts/default/trigger/HeaderTrigger.vue: -------------------------------------------------------------------------------- 1 | 4 | 24 | -------------------------------------------------------------------------------- /src/layouts/default/trigger/SiderTrigger.vue: -------------------------------------------------------------------------------- 1 | 7 | 22 | -------------------------------------------------------------------------------- /src/layouts/default/trigger/index.vue: -------------------------------------------------------------------------------- 1 | 5 | 23 | -------------------------------------------------------------------------------- /src/layouts/iframe/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 26 | -------------------------------------------------------------------------------- /src/layouts/page/transition.ts: -------------------------------------------------------------------------------- 1 | import type { FunctionalComponent } from 'vue'; 2 | import type { RouteLocation } from 'vue-router'; 3 | 4 | export interface DefaultContext { 5 | Component: FunctionalComponent & { type: Recordable }; 6 | route: RouteLocation; 7 | } 8 | 9 | export function getTransitionName({ 10 | route, 11 | openCache, 12 | cacheTabs, 13 | enableTransition, 14 | def, 15 | }: Pick & { 16 | enableTransition: boolean; 17 | openCache: boolean; 18 | def: string; 19 | cacheTabs: string[]; 20 | }): string | undefined { 21 | if (!enableTransition) { 22 | return undefined; 23 | } 24 | 25 | const isInCache = cacheTabs.includes(route.name as string); 26 | const transitionName = 'fade-slide'; 27 | let name: string | undefined = transitionName; 28 | 29 | if (openCache) { 30 | name = isInCache && route.meta.loaded ? transitionName : undefined; 31 | } 32 | return name || (route.meta.transitionName as string) || def; 33 | } 34 | -------------------------------------------------------------------------------- /src/locales/lang/en.ts: -------------------------------------------------------------------------------- 1 | import { genMessage } from '../helper'; 2 | import antdLocale from 'ant-design-vue/es/locale/en_US'; 3 | //import momentLocale from 'moment/dist/locale/eu'; 4 | 5 | const modules = import.meta.glob('./en/**/*.ts', { eager: true }); 6 | export default { 7 | message: { 8 | ...genMessage(modules as Recordable, 'en'), 9 | antdLocale, 10 | }, 11 | dateLocale: null, 12 | dateLocaleName: 'en', 13 | }; 14 | -------------------------------------------------------------------------------- /src/locales/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 | -------------------------------------------------------------------------------- /src/locales/lang/en/routes/basic.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | login: 'Login', 3 | errorLogList: 'Error Log', 4 | }; 5 | -------------------------------------------------------------------------------- /src/locales/lang/en/routes/dashboard.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | dashboard: 'Dashboard', 3 | about: 'About', 4 | workbench: 'Workbench', 5 | analysis: 'Analysis', 6 | }; 7 | -------------------------------------------------------------------------------- /src/locales/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 | -------------------------------------------------------------------------------- /src/locales/lang/zh-CN/routes/basic.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | login: '登录', 3 | errorLogList: '错误日志列表', 4 | }; 5 | -------------------------------------------------------------------------------- /src/locales/lang/zh-CN/routes/dashboard.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | dashboard: 'Dashboard', 3 | about: '关于', 4 | workbench: '工作台', 5 | analysis: '分析页', 6 | }; 7 | -------------------------------------------------------------------------------- /src/locales/lang/zh_CN.ts: -------------------------------------------------------------------------------- 1 | import { genMessage } from '../helper'; 2 | import antdLocale from 'ant-design-vue/es/locale/zh_CN'; 3 | 4 | const modules = import.meta.glob('./zh-CN/**/*.ts', { eager: true }); 5 | export default { 6 | message: { 7 | ...genMessage(modules as Recordable, 'zh-CN'), 8 | antdLocale, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /src/logics/mitt/routeChange.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 | 5 | import mitt from '/@/utils/mitt'; 6 | import type { RouteLocationNormalized } from 'vue-router'; 7 | import { getRawRoute } from '/@/utils'; 8 | 9 | const emitter = mitt(); 10 | 11 | const key = Symbol(); 12 | 13 | let lastChangeTab: RouteLocationNormalized; 14 | 15 | export function setRouteChange(lastChangeRoute: RouteLocationNormalized) { 16 | const r = getRawRoute(lastChangeRoute); 17 | emitter.emit(key, r); 18 | lastChangeTab = r; 19 | } 20 | 21 | export function listenerRouteChange(callback: (route: RouteLocationNormalized) => void, immediate = true) { 22 | emitter.on(key, callback); 23 | immediate && lastChangeTab && callback(lastChangeTab); 24 | } 25 | 26 | export function removeTabChangeListener() { 27 | emitter.clear(); 28 | } 29 | -------------------------------------------------------------------------------- /src/logics/theme/dark.ts: -------------------------------------------------------------------------------- 1 | import { darkCssIsReady, loadDarkThemeCss } from '@rys-fe/vite-plugin-theme/es/client'; 2 | import { addClass, hasClass, removeClass } from '/@/utils/domUtils'; 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 | -------------------------------------------------------------------------------- /src/logics/theme/updateColorWeak.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 | -------------------------------------------------------------------------------- /src/logics/theme/updateGrayMode.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 | -------------------------------------------------------------------------------- /src/logics/theme/util.ts: -------------------------------------------------------------------------------- 1 | const docEle = document.documentElement; 2 | export function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) { 3 | const targetEl = target || document.body; 4 | let { className } = targetEl; 5 | className = className.replace(clsName, ''); 6 | targetEl.className = flag ? `${className} ${clsName} ` : className; 7 | } 8 | 9 | export function setCssVar(prop: string, val: any, dom = docEle) { 10 | dom.style.setProperty(prop, val); 11 | } 12 | -------------------------------------------------------------------------------- /src/qiankun/apps.ts: -------------------------------------------------------------------------------- 1 | // /** 2 | // *微应用apps 3 | // * @name: 微应用名称 - 具有唯一性 4 | // * @entry: 微应用入口.必选 - 通过该地址加载微应用, 5 | // * @container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上 6 | // * @activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用 7 | // */ 8 | // //子应用列表 9 | // const _apps: object[] = []; 10 | // for (const key in import.meta.env) { 11 | // if (key.includes('VITE_APP_SUB_')) { 12 | // const name = key.split('VITE_APP_SUB_')[1]; 13 | // const obj = { 14 | // name, 15 | // entry: import.meta.env[key], 16 | // container: '#content', 17 | // activeRule: name, 18 | // }; 19 | // _apps.push(obj); 20 | // } 21 | // } 22 | // export const apps = _apps; 23 | -------------------------------------------------------------------------------- /src/qiankun/micro/index.ts: -------------------------------------------------------------------------------- 1 | import {qiankunWindow} from 'vite-plugin-qiankun/dist/helper' 2 | 3 | /** 4 | * 【JEECG作为乾坤子应用】【判断当前是否是以乾坤子应用的模式运行】 5 | */ 6 | export function checkIsQiankunMicro(): boolean { 7 | return !!qiankunWindow.__POWERED_BY_QIANKUN__; 8 | } 9 | 10 | export function getGlobal() { 11 | return (checkIsQiankunMicro() ? qiankunWindow : window) as Window 12 | } 13 | -------------------------------------------------------------------------------- /src/router/constant.ts: -------------------------------------------------------------------------------- 1 | export const REDIRECT_NAME = 'Redirect'; 2 | 3 | export const PARENT_LAYOUT_NAME = 'ParentLayout'; 4 | 5 | export const PAGE_NOT_FOUND_NAME = 'PageNotFound'; 6 | // update-begin--author:liaozhiyang---date:202401127---for:【issues/7500】vue-router4.5.0版本路由name:PageNotFound同名导致登录进不去 7 | export const PAGE_NOT_FOUND_NAME_404 = 'PageNotFound404'; 8 | // update-end--author:liaozhiyang---date:202401127---for:【issues/7500】vue-router4.5.0版本路由name:PageNotFound同名导致登录进不去 9 | 10 | export const EXCEPTION_COMPONENT = () => import('/@/views/sys/exception/Exception.vue'); 11 | 12 | /** 13 | * @description: default layout 14 | */ 15 | export const LAYOUT = () => import('/@/layouts/default/index.vue'); 16 | 17 | /** 18 | * @description: parent-layout 19 | */ 20 | export const getParentLayout = (_name?: string) => { 21 | return () => 22 | new Promise((resolve) => { 23 | resolve({ 24 | name: _name || PARENT_LAYOUT_NAME, 25 | }); 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /src/router/router.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * 路由实例存储文件,请勿轻易添加其他代码,防止出现 HMR 或其他问题 3 | */ 4 | import type {Router, RouterHistory} from 'vue-router'; 5 | import {createRouter as createVueRouter, createWebHistory, RouterOptions} from 'vue-router'; 6 | 7 | export let router: Router = null as unknown as Router; 8 | 9 | export function setRouter(r: Router) { 10 | router = r 11 | } 12 | 13 | let webHistory: Nullable = null; 14 | 15 | /** 16 | * 创建路由 17 | * @param options 参数 18 | */ 19 | export function createRouter(options: Partial) { 20 | webHistory = createWebHistory(import.meta.env.VITE_PUBLIC_PATH); 21 | // app router 22 | let router = createVueRouter({ 23 | history: webHistory, 24 | routes: [], 25 | ...options, 26 | }); 27 | 28 | setRouter(router) 29 | 30 | return router 31 | } 32 | 33 | // 销毁路由 34 | export function destroyRouter() { 35 | setRouter(null as unknown as Router); 36 | if (webHistory) { 37 | webHistory.destroy(); 38 | } 39 | webHistory = null 40 | } 41 | -------------------------------------------------------------------------------- /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 | */ 6 | import type { AppRouteModule } from '/@/router/types'; 7 | 8 | // test 9 | // http:ip:port/main-out 10 | export const mainOutRoutes: AppRouteModule[] = [ 11 | { 12 | path: '/main-out', 13 | name: 'MainOut', 14 | component: () => import('/@/views/demo/main-out/index.vue'), 15 | meta: { 16 | title: 'MainOut', 17 | ignoreAuth: true, 18 | }, 19 | }, 20 | ]; 21 | 22 | export const mainOutRouteNames = mainOutRoutes.map((item) => item.name); 23 | -------------------------------------------------------------------------------- /src/router/routes/modules/about.ts: -------------------------------------------------------------------------------- 1 | import type { AppRouteModule } from '/@/router/types'; 2 | 3 | import { LAYOUT } from '/@/router/constant'; 4 | import { t } from '/@/hooks/web/useI18n'; 5 | 6 | const dashboard: AppRouteModule = { 7 | path: '/about', 8 | name: 'About', 9 | component: LAYOUT, 10 | redirect: '/about/index', 11 | meta: { 12 | hideChildrenInMenu: true, 13 | icon: 'simple-icons:about-dot-me', 14 | title: t('routes.dashboard.about'), 15 | orderNo: 100000, 16 | }, 17 | children: [ 18 | { 19 | path: 'index', 20 | name: 'AboutPage', 21 | component: () => import('/@/views/sys/about/index.vue'), 22 | meta: { 23 | title: t('routes.dashboard.about'), 24 | icon: 'simple-icons:about-dot-me', 25 | hideMenu: true, 26 | }, 27 | }, 28 | ], 29 | }; 30 | 31 | export default dashboard; 32 | -------------------------------------------------------------------------------- /src/router/routes/modules/demo/setup.ts: -------------------------------------------------------------------------------- 1 | import type { AppRouteModule } from '/@/router/types'; 2 | 3 | import { LAYOUT } from '/@/router/constant'; 4 | import { t } from '/@/hooks/web/useI18n'; 5 | 6 | const setup: AppRouteModule = { 7 | path: '/setup', 8 | name: 'SetupDemo', 9 | component: LAYOUT, 10 | redirect: '/setup/index', 11 | meta: { 12 | orderNo: 90000, 13 | hideChildrenInMenu: true, 14 | icon: 'whh:paintroll', 15 | title: t('routes.demo.setup.page'), 16 | }, 17 | children: [ 18 | { 19 | path: 'index', 20 | name: 'SetupDemoPage', 21 | component: () => import('/@/views/demo/setup/index.vue'), 22 | meta: { 23 | title: t('routes.demo.setup.page'), 24 | icon: 'whh:paintroll', 25 | hideMenu: true, 26 | }, 27 | }, 28 | ], 29 | }; 30 | 31 | export default setup; 32 | -------------------------------------------------------------------------------- /src/router/routes/staticRouter.ts: -------------------------------------------------------------------------------- 1 | import type { AppRouteRecordRaw } from '/@/router/types'; 2 | import { LAYOUT } from '/@/router/constant'; 3 | 4 | export const AI_ROUTE: AppRouteRecordRaw = { 5 | path: '', 6 | name: 'ai-parent', 7 | component: LAYOUT, 8 | meta: { 9 | title: 'ai', 10 | }, 11 | children: [ 12 | { 13 | path: '/ai', 14 | name: 'ai', 15 | component: () => import('/@/views/dashboard/ai/index.vue'), 16 | meta: { 17 | title: 'AI助手', 18 | }, 19 | }, 20 | ], 21 | }; 22 | 23 | export const staticRoutesList = [AI_ROUTE]; 24 | -------------------------------------------------------------------------------- /src/settings/encryptionSetting.ts: -------------------------------------------------------------------------------- 1 | import { isDevMode } from '/@/utils/env'; 2 | 3 | // 缓存默认过期时间 4 | export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7; 5 | 6 | // 开启缓存加密后,加密密钥。采用aes加密 7 | export const cacheCipher = { 8 | key: '_11111000001111@', 9 | iv: '@11111000001111_', 10 | }; 11 | 12 | // 是否加密缓存,默认生产环境加密 13 | export const enableStorageEncryption = false; 14 | -------------------------------------------------------------------------------- /src/settings/localeSetting.ts: -------------------------------------------------------------------------------- 1 | import type { DropMenu } from '../components/Dropdown'; 2 | import type { LocaleSetting, LocaleType } from '/#/config'; 3 | 4 | export const LOCALE: { [key: string]: LocaleType } = { 5 | ZH_CN: 'zh_CN', 6 | EN_US: 'en', 7 | }; 8 | 9 | export const localeSetting: LocaleSetting = { 10 | // 是否显示语言选择器 11 | showPicker: true, 12 | // 当前语言 13 | locale: LOCALE.ZH_CN, 14 | // 默认语言 15 | fallback: LOCALE.ZH_CN, 16 | // 允许的语言 17 | availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US], 18 | }; 19 | 20 | // 语言列表 21 | export const localeList: DropMenu[] = [ 22 | { 23 | text: '简体中文', 24 | event: LOCALE.ZH_CN, 25 | }, 26 | { 27 | text: 'English', 28 | event: LOCALE.EN_US, 29 | }, 30 | ]; 31 | -------------------------------------------------------------------------------- /src/settings/siteSetting.ts: -------------------------------------------------------------------------------- 1 | // github repo url 2 | export const GITHUB_URL = 'https://github.com/testnet0/testnet'; 3 | 4 | // vue-Jeecg-admin-next-doc 5 | export const DOC_URL = 'https://testnet.shengkai.wang'; 6 | 7 | // site url 8 | export const SITE_URL = 'https://github.com/testnet0/testnet'; 9 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | import type { Pinia } from 'pinia'; 3 | import { createPinia } from 'pinia'; 4 | 5 | let app: Nullable> = null; 6 | let store: Nullable = null; 7 | 8 | export function setupStore($app: App) { 9 | if (store == null) { 10 | store = createPinia(); 11 | } 12 | app = $app; 13 | app.use(store); 14 | } 15 | 16 | // 销毁store 17 | export function destroyStore() { 18 | store = null; 19 | } 20 | 21 | // 获取app实例 22 | export const getAppContext = () => app?._context; 23 | 24 | export {app, store}; 25 | -------------------------------------------------------------------------------- /src/utils/dateUtil.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Independent time operation tool to facilitate subsequent switch to dayjs 3 | */ 4 | import dayjs from 'dayjs'; 5 | 6 | const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; 7 | const DATE_FORMAT = 'YYYY-MM-DD'; 8 | 9 | export function formatToDateTime(date: dayjs.Dayjs | undefined = undefined, format = DATE_TIME_FORMAT): string { 10 | return dayjs(date).format(format); 11 | } 12 | 13 | export function formatToDate(date: dayjs.Dayjs | undefined = undefined, format = DATE_FORMAT): string { 14 | return dayjs(date).format(format); 15 | } 16 | 17 | export const dateUtil = dayjs; 18 | -------------------------------------------------------------------------------- /src/utils/desform/customExpression.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * 这里填写用户自定义的表达式 4 | * 可用在Online表单的默认值表达式中使用 5 | * 需要外部使用的变量或方法一定要 export,否则无法识别 6 | * 示例: 7 | * export const name = '张三'; // const 是常量 8 | * export let age = 17; // 看情况 export const 还是 let ,两者都可正常使用 9 | * export function content(arg) { // export 方法,可传参数,使用时要加括号,值一定要return回去,可以返回Promise 10 | * return 'content' + arg; 11 | * } 12 | * export const address = (arg) => content(arg) + ' | 北京市'; // export 箭头函数也可以 13 | * 14 | */ 15 | 16 | /** 字段默认值官方示例:获取地址 */ 17 | export function demoFieldDefVal_getAddress(arg) { 18 | if (!arg) { 19 | arg = '朝阳区'; 20 | } 21 | return `北京市 ${arg}`; 22 | } 23 | 24 | /** 自定义JS函数示例 */ 25 | export function sayHi(name) { 26 | if (!name) { 27 | name = '张三'; 28 | } 29 | return `您好,我叫: ${name}`; 30 | } 31 | -------------------------------------------------------------------------------- /src/utils/helper/tsxHelper.tsx: -------------------------------------------------------------------------------- 1 | import { Slots } from 'vue'; 2 | import { isFunction } from '/@/utils/is'; 3 | 4 | /** 5 | * @description: Get slot to prevent empty error 6 | */ 7 | export function 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 function 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 | -------------------------------------------------------------------------------- /src/utils/log.ts: -------------------------------------------------------------------------------- 1 | const projectName = import.meta.env.VITE_GLOB_APP_TITLE; 2 | 3 | export function warn(message: string) { 4 | console.warn(`[${projectName} warn]:${message}`); 5 | } 6 | 7 | export function error(message: string) { 8 | throw new Error(`[${projectName} error]:${message}`); 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/monorepo/dynamicRouter.ts: -------------------------------------------------------------------------------- 1 | export type DynamicViewsRecord = Record Promise>; 2 | 3 | /** 已注册模块的动态页面 */ 4 | export const packageViews: DynamicViewsRecord = {}; 5 | 6 | /** 7 | * 注册动态路由页面 8 | * @param getViews 获取该模块下所有页面的方法 9 | */ 10 | export function registerDynamicRouter(getViews: () => DynamicViewsRecord) { 11 | if (typeof getViews === 'function') { 12 | let dynamicViews = getViews(); 13 | Object.keys(dynamicViews).forEach((key) => { 14 | // 处理动态页面的key,使其可以让路由识别 15 | let newKey = key.replace('./src/views', '../../views'); 16 | packageViews[newKey] = dynamicViews[key]; 17 | }); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/utils/uuid.ts: -------------------------------------------------------------------------------- 1 | const hexList: string[] = []; 2 | for (let i = 0; i <= 15; i++) { 3 | hexList[i] = i.toString(16); 4 | } 5 | 6 | export function buildUUID(): string { 7 | let uuid = ''; 8 | for (let i = 1; i <= 36; i++) { 9 | if (i === 9 || i === 14 || i === 19 || i === 24) { 10 | uuid += '-'; 11 | } else if (i === 15) { 12 | uuid += 4; 13 | } else if (i === 20) { 14 | uuid += hexList[(Math.random() * 4) | 8]; 15 | } else { 16 | uuid += hexList[(Math.random() * 16) | 0]; 17 | } 18 | } 19 | return uuid.replace(/-/g, ''); 20 | } 21 | 22 | let unique = 0; 23 | export function buildShortUUID(prefix = ''): string { 24 | const time = Date.now(); 25 | const random = Math.floor(Math.random() * 1000000000); 26 | unique++; 27 | return prefix + '_' + random + unique + String(time); 28 | } 29 | -------------------------------------------------------------------------------- /src/views/asset/api/index.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-address-list'; 3 | 4 | .@{prefix-cls} { 5 | // update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 6 | background-color: @component-background; 7 | // update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 8 | &--box { 9 | .ant-tabs-nav { 10 | padding: 0 20px; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/views/asset/search/AssetSearch.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | export enum Api { 4 | search = '/testnet.server/asset/search', 5 | import = '/testnet.server/asset/import', 6 | } 7 | 8 | /** 9 | 10 | /** 11 | * 获取API列表 12 | */ 13 | export const search = (params) => { 14 | return defHttp.post({ 15 | url: Api.search, 16 | timeout: 1000 * 60 * 2, 17 | params, 18 | }); 19 | }; 20 | 21 | /** 22 | * 获取API列表 23 | */ 24 | export const assetImport = (params) => { 25 | return defHttp.post({ 26 | url: Api.import, 27 | timeout: 1000 * 60 * 2, 28 | params, 29 | }); 30 | }; 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/views/dashboard/Analysis/api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | loginfo = '/sys/loginfo', 5 | visitInfo = '/sys/visitInfo', 6 | } 7 | /** 8 | * 日志统计信息 9 | * @param params 10 | */ 11 | export const getLoginfo = (params) => defHttp.get({ url: Api.loginfo, params }, { isTransformResponse: false }); 12 | /** 13 | * 访问量信息 14 | * @param params 15 | */ 16 | export const getVisitInfo = (params) => defHttp.get({ url: Api.visitInfo, params }, { isTransformResponse: false }); 17 | 18 | export const getAssetData = (params) => defHttp.get({ url: '/testnet.server/dashboard/getCardData', params }, { isTransformResponse: false }); 19 | 20 | export const getScriptData = (params) => defHttp.get({ url: '/testnet.server/dashboard/getScriptData', params }, { isTransformResponse: false }); 21 | -------------------------------------------------------------------------------- /src/views/dashboard/Analysis/components/SiteAnalysis.vue: -------------------------------------------------------------------------------- 1 | 11 | 34 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/views/dashboard/Analysis/homePage/IndexDef.vue: -------------------------------------------------------------------------------- 1 | 12 | 26 | -------------------------------------------------------------------------------- /src/views/dashboard/Analysis/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 12 | -------------------------------------------------------------------------------- /src/views/dashboard/ai/components/aide/images/ai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/dashboard/ai/components/aide/images/ai.png -------------------------------------------------------------------------------- /src/views/dashboard/ai/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 13 | 14 | 25 | -------------------------------------------------------------------------------- /src/views/dashboard/workbench/components/QuickNav.vue: -------------------------------------------------------------------------------- 1 | 13 | 20 | -------------------------------------------------------------------------------- /src/views/demo/comp/drawer/Drawer1.vue: -------------------------------------------------------------------------------- 1 | 4 | 14 | -------------------------------------------------------------------------------- /src/views/demo/comp/drawer/Drawer2.vue: -------------------------------------------------------------------------------- 1 | 7 | 18 | -------------------------------------------------------------------------------- /src/views/demo/comp/drawer/Drawer5.vue: -------------------------------------------------------------------------------- 1 | 7 | 14 | -------------------------------------------------------------------------------- /src/views/demo/comp/lazy/TargetContent.vue: -------------------------------------------------------------------------------- 1 | 9 | 20 | -------------------------------------------------------------------------------- /src/views/demo/comp/modal/Modal2.vue: -------------------------------------------------------------------------------- 1 | 7 | 24 | -------------------------------------------------------------------------------- /src/views/demo/comp/modal/Modal3.vue: -------------------------------------------------------------------------------- 1 | 6 | 16 | -------------------------------------------------------------------------------- /src/views/demo/comp/scroll/index.vue: -------------------------------------------------------------------------------- 1 | 16 | 25 | 32 | -------------------------------------------------------------------------------- /src/views/demo/comp/strength-meter/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 26 | 33 | -------------------------------------------------------------------------------- /src/views/demo/comp/verify/Rotate.vue: -------------------------------------------------------------------------------- 1 | 8 | 29 | 34 | -------------------------------------------------------------------------------- /src/views/demo/document/form/BasicFormComponent.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 24 | 25 | 35 | -------------------------------------------------------------------------------- /src/views/demo/document/form/BasicFormCustom.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/views/demo/document/form/BasicFormCustomComponent.vue: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 22 | 23 | 33 | -------------------------------------------------------------------------------- /src/views/demo/editor/tinymce/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 22 | -------------------------------------------------------------------------------- /src/views/demo/feat/breadcrumb/ChildrenList.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | -------------------------------------------------------------------------------- /src/views/demo/feat/breadcrumb/ChildrenListDetail.vue: -------------------------------------------------------------------------------- 1 | 6 | 11 | -------------------------------------------------------------------------------- /src/views/demo/feat/breadcrumb/FlatList.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | -------------------------------------------------------------------------------- /src/views/demo/feat/breadcrumb/FlatListDetail.vue: -------------------------------------------------------------------------------- 1 | 4 | 9 | -------------------------------------------------------------------------------- /src/views/demo/feat/ripple/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 18 | 19 | 32 | -------------------------------------------------------------------------------- /src/views/demo/feat/tab-params/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 28 | -------------------------------------------------------------------------------- /src/views/demo/feat/tabs/TabDetail.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 29 | -------------------------------------------------------------------------------- /src/views/demo/level/Menu111.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | -------------------------------------------------------------------------------- /src/views/demo/level/Menu12.vue: -------------------------------------------------------------------------------- 1 | 8 | 13 | -------------------------------------------------------------------------------- /src/views/demo/level/Menu2.vue: -------------------------------------------------------------------------------- 1 | 8 | 16 | -------------------------------------------------------------------------------- /src/views/demo/main-out/index.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /src/views/demo/page/list/basic/data.tsx: -------------------------------------------------------------------------------- 1 | export const cardList = (() => { 2 | const result: any[] = []; 3 | for (let i = 0; i < 6; i++) { 4 | result.push({ 5 | id: i, 6 | title: 'Jeecg Admin', 7 | description: '基于Vue Next, TypeScript, Ant Design Vue实现的一套完整的企业级后台管理系统', 8 | datetime: '2020-11-26 17:39', 9 | extra: '编辑', 10 | icon: 'logos:vue', 11 | color: '#1890ff', 12 | author: 'Jeecg', 13 | percent: 20 * (i + 1), 14 | }); 15 | } 16 | return result; 17 | })(); 18 | -------------------------------------------------------------------------------- /src/views/demo/page/list/card/data.tsx: -------------------------------------------------------------------------------- 1 | export const cardList = (() => { 2 | const result: any[] = []; 3 | for (let i = 0; i < 12; i++) { 4 | result.push({ 5 | title: 'Jeecg Admin', 6 | icon: 'logos:vue', 7 | color: '#1890ff', 8 | active: '100', 9 | new: '1,799', 10 | download: 'bx:bx-download', 11 | }); 12 | } 13 | return result; 14 | })(); 15 | -------------------------------------------------------------------------------- /src/views/demo/permission/front/AuthPageA.vue: -------------------------------------------------------------------------------- 1 | 4 | 8 | 20 | -------------------------------------------------------------------------------- /src/views/demo/permission/front/AuthPageB.vue: -------------------------------------------------------------------------------- 1 | 4 | 8 | 20 | -------------------------------------------------------------------------------- /src/views/demo/table/MergeHeader.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | -------------------------------------------------------------------------------- /src/views/demo/table/MultipleHeader.vue: -------------------------------------------------------------------------------- 1 | 6 | 27 | -------------------------------------------------------------------------------- /src/views/demo/tree/data.ts: -------------------------------------------------------------------------------- 1 | import { TreeItem } from '/@/components/Tree/index'; 2 | 3 | export const treeData: TreeItem[] = [ 4 | { 5 | title: 'parent ', 6 | key: '0-0', 7 | children: [ 8 | { title: 'leaf', key: '0-0-0' }, 9 | { 10 | title: 'leaf', 11 | key: '0-0-1', 12 | children: [ 13 | { title: 'leaf', key: '0-0-0-0', children: [{ title: 'leaf', key: '0-0-0-0-1' }] }, 14 | { title: 'leaf', key: '0-0-0-1' }, 15 | ], 16 | }, 17 | ], 18 | }, 19 | { 20 | title: 'parent 2', 21 | key: '1-1', 22 | children: [ 23 | { title: 'leaf', key: '1-1-0' }, 24 | { title: 'leaf', key: '1-1-1' }, 25 | ], 26 | }, 27 | { 28 | title: 'parent 3', 29 | key: '2-2', 30 | children: [ 31 | { title: 'leaf', key: '2-2-0' }, 32 | { title: 'leaf', key: '2-2-1' }, 33 | ], 34 | }, 35 | ]; 36 | -------------------------------------------------------------------------------- /src/views/demo/vextable/api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | list = '/test/jeecgOrderMain/list', 5 | delete = '/test/jeecgOrderMain/delete', 6 | orderCustomerList = '/test/jeecgOrderMain/queryOrderCustomerListByMainId', 7 | orderTicketList = '/test/jeecgOrderMain/queryOrderTicketListByMainId', 8 | } 9 | 10 | /** 11 | * 列表接口 12 | * @param params 13 | */ 14 | export const list = (params) => defHttp.get({ url: Api.list, params }); 15 | /** 16 | * 子表单信息 17 | * @param params 18 | */ 19 | export const orderTicketList = (params) => defHttp.get({ url: Api.orderTicketList, params }); 20 | /** 21 | * 子表单信息 22 | * @param params 23 | */ 24 | export const orderCustomerList = (params) => defHttp.get({ url: Api.orderCustomerList, params }); 25 | /** 26 | * 删除用户 27 | */ 28 | export const deleteOne = (params, handleSuccess) => { 29 | return defHttp.delete({ url: Api.delete, params }, { joinParamsToUrl: true }).then(() => { 30 | handleSuccess(); 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /src/views/demo/vextable/jvxetable/jvxetable.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | enum Api { 3 | save = '/test/jeecgOrderMain/add', 4 | edit = '/test/jeecgOrderMain/edit', 5 | orderCustomerList = '/test/jeecgOrderMain/queryOrderCustomerListByMainId', 6 | orderTicketList = '/test/jeecgOrderMain/queryOrderTicketListByMainId', 7 | } 8 | export const orderCustomerList = Api.orderCustomerList; 9 | export const orderTicketList = Api.orderTicketList; 10 | /** 11 | * 保存或者更新 12 | * @param params 13 | */ 14 | export const saveOrUpdate = (params, isUpdate) => { 15 | let url = isUpdate ? Api.edit : Api.save; 16 | return defHttp.post({ url: url, params }); 17 | }; 18 | -------------------------------------------------------------------------------- /src/views/monitor/datalog/datalog.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | list = '/sys/dataLog/list', 5 | queryDataVerList = '/sys/dataLog/queryDataVerList', 6 | queryCompareList = '/sys/dataLog/queryCompareList', 7 | } 8 | 9 | /** 10 | * 查询数据日志列表 11 | * @param params 12 | */ 13 | export const getDataLogList = (params) => { 14 | return defHttp.get({ url: Api.list, params }); 15 | }; 16 | 17 | /** 18 | * 查询数据日志列表 19 | * @param params 20 | */ 21 | export const queryDataVerList = (params) => { 22 | return defHttp.get({ url: Api.queryDataVerList, params }); 23 | }; 24 | 25 | /** 26 | * 查询对比数据 27 | * @param params 28 | */ 29 | export const queryCompareList = (params) => { 30 | return defHttp.get({ url: Api.queryCompareList, params }); 31 | }; 32 | -------------------------------------------------------------------------------- /src/views/monitor/datalog/datalog.data.ts: -------------------------------------------------------------------------------- 1 | import { BasicColumn, FormSchema } from '/@/components/Table'; 2 | 3 | export const columns: BasicColumn[] = [ 4 | { 5 | title: '表名', 6 | dataIndex: 'dataTable', 7 | width: 150, 8 | align: 'left', 9 | }, 10 | { 11 | title: '数据ID', 12 | dataIndex: 'dataId', 13 | width: 350, 14 | }, 15 | { 16 | title: '版本号', 17 | dataIndex: 'dataVersion', 18 | width: 100, 19 | }, 20 | { 21 | title: '数据内容', 22 | dataIndex: 'dataContent', 23 | }, 24 | { 25 | title: '创建人', 26 | dataIndex: 'createBy', 27 | sorter: true, 28 | width: 200, 29 | }, 30 | ]; 31 | 32 | export const searchFormSchema: FormSchema[] = [ 33 | { 34 | field: 'dataTable', 35 | label: '表名', 36 | component: 'Input', 37 | colProps: { span: 8 }, 38 | }, 39 | { 40 | field: 'dataId', 41 | label: '数据ID', 42 | component: 'Input', 43 | colProps: { span: 8 }, 44 | }, 45 | ]; 46 | -------------------------------------------------------------------------------- /src/views/monitor/disk/disk.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | queryDiskInfo = '/sys/actuator/redis/queryDiskInfo', 5 | } 6 | 7 | /** 8 | * 详细信息 9 | */ 10 | export const queryDiskInfo = () => { 11 | return defHttp.get({ url: Api.queryDiskInfo }, { successMessageMode: 'none' }); 12 | }; 13 | -------------------------------------------------------------------------------- /src/views/monitor/log/log.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | list = '/sys/log/list', 5 | } 6 | 7 | /** 8 | * 查询日志列表 9 | * @param params 10 | */ 11 | export const getLogList = (params) => { 12 | return defHttp.get({ url: Api.list, params }); 13 | }; 14 | -------------------------------------------------------------------------------- /src/views/monitor/redis/redis.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | keysSize = '/sys/actuator/redis/keysSize', 5 | memoryInfo = '/sys/actuator/redis/memoryInfo', 6 | info = '/sys/actuator/redis/info', 7 | metricsHistory = '/sys/actuator/redis/metrics/history', 8 | } 9 | 10 | /** 11 | * key个数 12 | */ 13 | export const getKeysSize = () => { 14 | return defHttp.get({ url: Api.keysSize }, { isTransformResponse: false }); 15 | }; 16 | 17 | /** 18 | * 内存信息 19 | */ 20 | export const getMemoryInfo = () => { 21 | return defHttp.get({ url: Api.memoryInfo }, { isTransformResponse: false }); 22 | }; 23 | 24 | /** 25 | * 详细信息 26 | */ 27 | export const getInfo = () => { 28 | return defHttp.get({ url: Api.info }); 29 | }; 30 | 31 | /** 32 | * 历史监控记录 33 | */ 34 | export const getMetricsHistory = () => { 35 | return defHttp.get({ url: Api.metricsHistory }); 36 | }; 37 | 38 | export const getRedisInfo = () => { 39 | return Promise.all([getKeysSize(), getMemoryInfo()]); 40 | }; 41 | -------------------------------------------------------------------------------- /src/views/monitor/redis/redis.data.ts: -------------------------------------------------------------------------------- 1 | import { BasicColumn } from '/@/components/Table'; 2 | 3 | export const columns: BasicColumn[] = [ 4 | { 5 | title: 'Key', 6 | dataIndex: 'key', 7 | width: 100, 8 | }, 9 | { 10 | title: 'Description', 11 | dataIndex: 'description', 12 | width: 80, 13 | }, 14 | { 15 | title: 'Value', 16 | dataIndex: 'value', 17 | width: 80, 18 | }, 19 | ]; 20 | -------------------------------------------------------------------------------- /src/views/monitor/server/server.data.ts: -------------------------------------------------------------------------------- 1 | import { BasicColumn } from '/@/components/Table'; 2 | 3 | export const columns: BasicColumn[] = [ 4 | { 5 | title: '参数', 6 | dataIndex: 'param', 7 | width: 80, 8 | align: 'left', 9 | slots: { customRender: 'param' }, 10 | }, 11 | { 12 | title: '描述', 13 | dataIndex: 'text', 14 | slots: { customRender: 'text' }, 15 | width: 80, 16 | }, 17 | { 18 | title: '当前值', 19 | dataIndex: 'value', 20 | slots: { customRender: 'value' }, 21 | width: 80, 22 | }, 23 | ]; 24 | -------------------------------------------------------------------------------- /src/views/monitor/trace/trace.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | enum Api { 4 | actuatorList = '/actuator/jeecghttptrace/', 5 | } 6 | 7 | /** 8 | * 追踪信息 9 | */ 10 | export const getActuatorList = (query: String, order: String) => { 11 | return defHttp.get({ url: Api.actuatorList + query + '/' + order }, { isTransformResponse: false }); 12 | }; 13 | -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/chat/AiChatIcon.vue: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiapp/chat/AiChatIcon.vue -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/chat/hooks/useChat.ts: -------------------------------------------------------------------------------- 1 | import { useChatStore } from '@/store'; 2 | 3 | export function useChat() { 4 | const chatStore = useChatStore(); 5 | 6 | const getChatByUuidAndIndex = (uuid: number, index: number) => { 7 | return chatStore.getChatByUuidAndIndex(uuid, index); 8 | }; 9 | 10 | const addChat = (uuid: number, chat: Chat.Chat) => { 11 | chatStore.addChatByUuid(uuid, chat); 12 | }; 13 | 14 | const updateChat = (uuid: number, index: number, chat: Chat.Chat) => { 15 | chatStore.updateChatByUuid(uuid, index, chat); 16 | }; 17 | 18 | const updateChatSome = (uuid: number, index: number, chat: Partial) => { 19 | chatStore.updateChatSomeByUuid(uuid, index, chat); 20 | }; 21 | 22 | return { 23 | addChat, 24 | updateChat, 25 | updateChatSome, 26 | getChatByUuidAndIndex, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/chat/js/chat.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiapp/chat/js/chat.js -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/img/ailogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiapp/img/ailogo.png -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/img/iconWebEmbedded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiapp/img/iconWebEmbedded.png -------------------------------------------------------------------------------- /src/views/super/airag/aiapp/img/webEmbedded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiapp/img/webEmbedded.png -------------------------------------------------------------------------------- /src/views/super/airag/aiknowledge/icon/draft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiknowledge/icon/draft.png -------------------------------------------------------------------------------- /src/views/super/airag/aiknowledge/icon/knowledge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aiknowledge/icon/knowledge.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/OpenAi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/OpenAi.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/deepspeek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/deepspeek.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/ollama.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/ollama.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/qianfan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/qianfan.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/qianwen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/qianwen.png -------------------------------------------------------------------------------- /src/views/super/airag/aimodel/icon/zhipuai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testnet0/testnet-vue3/126ab1db5e9609d9630a362b1b5a9a97d6701854/src/views/super/airag/aimodel/icon/zhipuai.png -------------------------------------------------------------------------------- /src/views/super/registerSuper.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | 3 | /** 4 | * 动态引入 super 下的组件 5 | */ 6 | export async function registerSuper(app: App) { 7 | const modules = import.meta.glob('./**/register.ts'); 8 | for (let [url, module] of Object.entries(modules)) { 9 | let { register } = await module(); 10 | if (typeof register === 'function') { 11 | await register(app); 12 | } else { 13 | console.error(`${url} 没有导出 register 函数,无法完成注册!`); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/views/sys/error-log/DetailModal.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | -------------------------------------------------------------------------------- /src/views/sys/exception/NetworkErrorException.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /src/views/sys/exception/NotAccessException.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /src/views/sys/exception/NotDataErrorException.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /src/views/sys/exception/ServerErrorException.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /src/views/sys/exception/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Exception } from './Exception.vue'; 2 | export { default as NotAccessException } from './NotAccessException.vue'; 3 | export { default as NetworkErrorException } from './NetworkErrorException.vue'; 4 | export { default as NotDataErrorException } from './NotDataErrorException.vue'; 5 | export { default as ServerErrorException } from './ServerErrorException.vue'; 6 | -------------------------------------------------------------------------------- /src/views/sys/iframe/FrameBlank.vue: -------------------------------------------------------------------------------- 1 | 4 | 10 | -------------------------------------------------------------------------------- /src/views/sys/lock/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | -------------------------------------------------------------------------------- /src/views/sys/login/LoginFormTitle.vue: -------------------------------------------------------------------------------- 1 | 6 | 26 | -------------------------------------------------------------------------------- /src/views/system/address/address.api.ts: -------------------------------------------------------------------------------- 1 | import { defHttp } from '/@/utils/http/axios'; 2 | 3 | export enum Api { 4 | list = '/sys/user/queryByOrgCodeForAddressList', 5 | positionList = '/sys/position/list', 6 | queryDepartTreeSync = '/sys/sysDepart/queryDepartTreeSync', 7 | } 8 | /** 9 | * 获取部门树列表 10 | */ 11 | export const queryDepartTreeSync = (params?) => defHttp.get({ url: Api.queryDepartTreeSync, params }); 12 | /** 13 | * 部门用户信息 14 | */ 15 | export const list = (params?) => defHttp.get({ url: Api.list, params }); 16 | /** 17 | * 职务list 18 | */ 19 | export const positionList = (params?) => defHttp.get({ url: Api.positionList, params }); 20 | -------------------------------------------------------------------------------- /src/views/system/address/index.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-address-list'; 3 | 4 | .@{prefix-cls} { 5 | // update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 6 | background-color: @component-background; 7 | // update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 8 | &--box { 9 | .ant-tabs-nav { 10 | padding: 0 20px; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/views/system/depart/index.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-depart-manage'; 3 | 4 | .@{prefix-cls} { 5 | // update-begin-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 6 | background: @component-background; 7 | // update-end-author:liusq date:20230625 for: [issues/563]暗色主题部分失效 8 | 9 | &--box { 10 | .ant-tabs-nav { 11 | padding: 0 20px; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/views/system/message/manage/ManageDrawer.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 25 | -------------------------------------------------------------------------------- /src/views/system/message/manage/index.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-message-manage'; 3 | 4 | .@{prefix-cls} { 5 | } 6 | -------------------------------------------------------------------------------- /src/views/system/message/template/index.less: -------------------------------------------------------------------------------- 1 | //noinspection LessUnresolvedVariable 2 | @prefix-cls: ~'@{namespace}-message-template'; 3 | 4 | .@{prefix-cls} { 5 | } 6 | -------------------------------------------------------------------------------- /src/views/system/notice/DetailModal.vue: -------------------------------------------------------------------------------- 1 |