├── .gitignore ├── admin-views ├── .eslintignore ├── src │ ├── service │ │ ├── api │ │ │ ├── index.ts │ │ │ ├── auth.ts │ │ │ └── base.ts │ │ └── request │ │ │ ├── index.ts │ │ │ └── config.ts │ ├── components │ │ ├── AmisEditor │ │ │ └── style │ │ │ │ └── index.less │ │ └── AmisRender │ │ │ └── CustomComponents │ │ │ ├── components │ │ │ ├── SvgIcon │ │ │ │ └── index.tsx │ │ │ └── Watermark │ │ │ │ └── index.tsx │ │ │ └── index.tsx │ ├── pages │ │ ├── 404 │ │ │ └── index.tsx │ │ └── login │ │ │ ├── AmisLogin │ │ │ └── index.tsx │ │ │ └── DefaultLogin │ │ │ └── bg │ │ │ └── style │ │ │ └── index.module.css │ ├── hooks │ │ ├── useSmallScreen.ts │ │ ├── useStore.ts │ │ ├── useSetting.ts │ │ └── useLang.ts │ ├── context.tsx │ ├── utils │ │ ├── lazyload.tsx │ │ ├── proxy.ts │ │ ├── clipboard.ts │ │ ├── dynamicAssets.ts │ │ └── useStorage.ts │ ├── layouts │ │ ├── components │ │ │ ├── IconButton │ │ │ │ └── index.tsx │ │ │ ├── LayoutTopBar │ │ │ │ └── components │ │ │ │ │ ├── FullscreenButton │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── SettingButton │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── RefreshButton │ │ │ │ │ └── index.tsx │ │ │ │ │ └── DarkThemeButton │ │ │ │ │ └── index.tsx │ │ │ ├── LayoutFooter │ │ │ │ └── index.tsx │ │ │ └── CollapseTrigger │ │ │ │ └── index.tsx │ │ └── TopLayout │ │ │ └── index.tsx │ ├── typeings.d.ts │ ├── global.css │ └── routes │ │ └── helpers.ts ├── dist │ ├── assets │ │ ├── __vite-browser-external-BIHI7g3E.js │ │ ├── App-BLLdMHlv.js.gz │ │ ├── Log-C0-dPJfq.js.gz │ │ ├── Nav-BxmCsdqM.js.gz │ │ ├── Tag-Dss3zF2C.js.gz │ │ ├── Tpl-D3Ejrn15.js.gz │ │ ├── bat-DPkNLes8.js.gz │ │ ├── cpp-RmZVvII3.js.gz │ │ ├── csp-C46ZqvIl.js.gz │ │ ├── css-yEtxmcUf.js.gz │ │ ├── doc-DCpobRJa.js.gz │ │ ├── ecl-BO6FnfXk.js.gz │ │ ├── empty-t2YotbAe.png │ │ ├── go-O9LJTZXk.js.gz │ │ ├── hcl-DxDQ3s82.js.gz │ │ ├── hls-B6NXaoPE.js.gz │ │ ├── lua-D28Ae8-K.js.gz │ │ ├── m3-DPitgjJI.js.gz │ │ ├── php-120yhfDK.js.gz │ │ ├── pla-CjnFlu4u.js.gz │ │ ├── pug-kFxLfcjb.js.gz │ │ ├── r-BIFz-_sK.js.gz │ │ ├── sb-BYAiYHFx.js.gz │ │ ├── sql-BdTr02Mf.js.gz │ │ ├── st-C8kzSboH.js.gz │ │ ├── tcl-PloMZuKG.js.gz │ │ ├── vb-BwAE3J76.js.gz │ │ ├── xml-CoKk4p_V.js.gz │ │ ├── Audio-lQtXBVUe.js.gz │ │ ├── CRUD-CtLy4SjK.js.gz │ │ ├── CRUD2-_-xiOBOz.js.gz │ │ ├── Card2-BOZba6jR.js.gz │ │ ├── Cards-1jZKYbYp.js.gz │ │ ├── Chart-C1ymjQbM.js.gz │ │ ├── Code-Zqn_up2e.js.gz │ │ ├── Combo-DCjkjGTi.js.gz │ │ ├── Date-DAUcdMzZ.js.gz │ │ ├── Each-BcLVRXns.js.gz │ │ ├── Flex-DpZkwwck.js.gz │ │ ├── Group-DftOoVYy.js.gz │ │ ├── Icon-DIPZTv9B.js.gz │ │ ├── Json-33n6be_T.js.gz │ │ ├── Link-B5v7OQvd.js.gz │ │ ├── Page-3Wveki9h.js.gz │ │ ├── Panel-CFVWnhcR.js.gz │ │ ├── Plain-D0Ub5Iv4.js.gz │ │ ├── Radio-MMA-Ygb5.js.gz │ │ ├── Steps-CHGPvVKH.js.gz │ │ ├── Tabs-kLVVGEgJ.js.gz │ │ ├── Tasks-CfiJvPE0.js.gz │ │ ├── Video-BJCfZpyH.js.gz │ │ ├── Words-DS3rkoYZ.js.gz │ │ ├── abap-CRCWOmpq.js.gz │ │ ├── apex-BL_CmIl-.js.gz │ │ ├── bicep-DLNwh9K6.js.gz │ │ ├── bmap-aUnw2Cn1.js.gz │ │ ├── codicon-B_ROkMI2.ttf │ │ ├── dart-D8lhlL1r.js.gz │ │ ├── flow9-Cac8vKd7.js.gz │ │ ├── html-D6WosyeW.js.gz │ │ ├── index-C9DuXPTk.js.gz │ │ ├── index-CEmnTf-r.js.gz │ │ ├── index-CIygZa3i.js.gz │ │ ├── index-Cf5G-36k.js.gz │ │ ├── index-CjzcObq8.js.gz │ │ ├── index-DVK099C8.js.gz │ │ ├── index-JCl9Kdsi.js.gz │ │ ├── index-k3UgEtTu.js.gz │ │ ├── java-SYsfObOQ.js.gz │ │ ├── julia-DQXNmw_w.js.gz │ │ ├── less-B86-qBTk.js.gz │ │ ├── lexon-Canl7DCW.js.gz │ │ ├── main-BW4IIgVO.js.gz │ │ ├── mips-CdjsipkG.js.gz │ │ ├── msdax-CYqgjx_P.js.gz │ │ ├── mysql-uE-sL1AK.js.gz │ │ ├── perl-DlYyT36c.js.gz │ │ ├── pgsql-DYSgOGm2.js.gz │ │ ├── razor-BVMWYSNN.js.gz │ │ ├── redis-CHOsPHWR.js.gz │ │ ├── ruby-CYWGW-b1.js.gz │ │ ├── rust-DMDD0SHb.js.gz │ │ ├── scala-Bqvq8jcR.js.gz │ │ ├── scss-CdQcnAnq.js.gz │ │ ├── shell-CmmbcNmB.js.gz │ │ ├── swift-vE6e-x0J.js.gz │ │ ├── twig-bne2BnKZ.js.gz │ │ ├── xlsx-B6sNpj_1.js.gz │ │ ├── yaml-A89blxgn.js.gz │ │ ├── Avatar-CvuOXqgm.js.gz │ │ ├── BarCode-QQbRJ0jq.js.gz │ │ ├── Carousel-BoBKWFw_.js.gz │ │ ├── CityDB-CDK2V0VV.js.gz │ │ ├── Custom-oIxyqSMq.js.gz │ │ ├── Dialog-DaEYX8jO.js.gz │ │ ├── Divider-ai0lfNQr.js.gz │ │ ├── Drawer-W5B6Ngm3.js.gz │ │ ├── Formula-CfhhCviC.js.gz │ │ ├── Grid2D-Bca2T_Vc.js.gz │ │ ├── GridNav-Ck4ekt-U.js.gz │ │ ├── IFrame-p6Z7j9yP.js.gz │ │ ├── Images-BXLjSmRS.js.gz │ │ ├── InputTag-Dc7A5unS.js.gz │ │ ├── Mapping-DsRtjekv.js.gz │ │ ├── Markdown-B5WiajtE.js.gz │ │ ├── Markdown-Cy08GKsO.js.gz │ │ ├── Number-BUnbYTq2.js.gz │ │ ├── Picker-DbAI9BjR.js.gz │ │ ├── Portlet-D1M4VnEb.js.gz │ │ ├── Progress-MCys3E2Y.js.gz │ │ ├── Property-BeLOVhDi.js.gz │ │ ├── QRCode-BVoow0vj.js.gz │ │ ├── Radios-BuwDFURq.js.gz │ │ ├── RichText-D-Qg8IsN.js.gz │ │ ├── Select-B6WmAJdh.js.gz │ │ ├── Service-D6sK8uvA.js.gz │ │ ├── Slider-DjuJGZ5M.js.gz │ │ ├── Status-C3T4ijKe.js.gz │ │ ├── Switch-OmepaNXL.js.gz │ │ ├── Textarea-mtRcTOil.js.gz │ │ ├── Timeline-OLnsY9Bg.js.gz │ │ ├── Tinymce-B9KBvA_N.js.gz │ │ ├── Transfer-CE61e_pP.js.gz │ │ ├── Wizard-Dc-oKxSc.js.gz │ │ ├── cameligo-CGrWLZr3.js.gz │ │ ├── clojure-D9WOWImG.js.gz │ │ ├── coffee-B7EJu28W.js.gz │ │ ├── csharp-BoL64M5l.js.gz │ │ ├── cssMode-D0eRU1jb.js.gz │ │ ├── editor-DaTjv5g2.css.gz │ │ ├── elixir-B9GXSzSz.js.gz │ │ ├── fsharp-fd1GTHhf.js.gz │ │ ├── graphql-LQdxqEYJ.js.gz │ │ ├── htmlMode-DYonAqdg.js.gz │ │ ├── iconfont-D1vFA1JF.ttf │ │ ├── iconfont-DbOOEIpE.woff │ │ ├── iconfont-cDH2QQwA.eot │ │ ├── index-DrO7jWyx.css.gz │ │ ├── jsonMode-DGyRX7T9.js.gz │ │ ├── kotlin-qQ0MG-9I.js.gz │ │ ├── liquid-GaJMa96o.js.gz │ │ ├── markdown-XFFkuszK.js.gz │ │ ├── mpegts-DBRfWjb-.js.gz │ │ ├── nav-mode-CYcEcVvH.png │ │ ├── pascal-BhNW15KB.js.gz │ │ ├── postiats-CQpG440k.js.gz │ │ ├── protobuf-UZVfc1EA.js.gz │ │ ├── python-CqxAmncV.js.gz │ │ ├── qsharp-BhgV_cYv.js.gz │ │ ├── redshift-w2XKkDvD.js.gz │ │ ├── scheme-Dhb-2j9p.js.gz │ │ ├── simple-CP5TPDeW.js.gz │ │ ├── solidity-CME5AdoB.js.gz │ │ ├── sophia-RYC1BQQz.js.gz │ │ ├── sparql-KEyrF7De.js.gz │ │ ├── tsMode-Bg2k5nC7.js.gz │ │ ├── AnchorNav-CnMxKLVd.js.gz │ │ ├── Checkboxes-CIOUrSJ3.js.gz │ │ ├── Container-CDosur4B.js.gz │ │ ├── DiffEditor-Da4i9CSn.js.gz │ │ ├── IconPicker-Bfy2vfuJ.js.gz │ │ ├── IconSelect-CmsMK3V_.js.gz │ │ ├── InputCity-DRu9JLn4.js.gz │ │ ├── InputColor-B1H9OsY3.js.gz │ │ ├── InputDate-BRQWnCdy.js.gz │ │ ├── InputExcel-BxL7dDMD.js.gz │ │ ├── InputGroup-CckGvNfV.js.gz │ │ ├── InputRange-BGlFclnM.js.gz │ │ ├── InputTable-Cmqxre4u.js.gz │ │ ├── InputText-BRtL4ZFR.js.gz │ │ ├── InputTree-CHXQANaO.js.gz │ │ ├── ListSelect-BvAmn-Pa.js.gz │ │ ├── Pagination-7hQWoF5V.js.gz │ │ ├── PdfViewer-Cq3SMB2w.js.gz │ │ ├── PdfViewer-DWq-KvyO.js.gz │ │ ├── SearchBox-CRWfxsqU.js.gz │ │ ├── TableView-Dgqk3f6s.js.gz │ │ ├── TreeSelect-59Pl5V3B.js.gz │ │ ├── UserSelect-Dbn0qm06.js.gz │ │ ├── codemirror-CNCHanJM.js.gz │ │ ├── dockerfile-DLk6rpji.js.gz │ │ ├── fa-solid-900-BAw_JAW6.ttf │ │ ├── handlebars-C_S5rpy5.js.gz │ │ ├── htmlmixed-BW5mNHl4.js.gz │ │ ├── javascript-CvYo9acX.js.gz │ │ ├── multiplex-BvG3wuIF.js.gz │ │ ├── pascaligo-5jv8CcQD.js.gz │ │ ├── powerquery-DdJtto1Z.js.gz │ │ ├── powershell-Bu_VLpJB.js.gz │ │ ├── typescript-Dgyh4mcD.js.gz │ │ ├── ChainedSelect-CwaV1yf2.js.gz │ │ ├── ChartRadios-ChYWBH2u.js.gz │ │ ├── CollapseGroup-CFxKs9BJ.js.gz │ │ ├── ColorPicker-Ba-arFiF.js.gz │ │ ├── ColumnToggler-ClJ6Go5M.js.gz │ │ ├── InputFormula-C3f4YfqN.js.gz │ │ ├── InputNumber-Bm6FFPtY.js.gz │ │ ├── InputRating-dG9af584.js.gz │ │ ├── InputRepeat-0K_l7HRj.js.gz │ │ ├── InputSubForm-CE1tadQg.js.gz │ │ ├── NestedSelect-CFMkOERr.js.gz │ │ ├── OfficeViewer-wRCiWdYL.js.gz │ │ ├── TabsTransfer-BCzipVSa.js.gz │ │ ├── editor.main-F140LpxE.js.gz │ │ ├── exceljs.min-DPm6Fun1.js.gz │ │ ├── fa-brands-400-BU4mH_I_.woff2 │ │ ├── fa-brands-400-CArp7j8S.ttf │ │ ├── fa-regular-400-D4OwLFL7.ttf │ │ ├── fa-solid-900-CcrrL0x0.woff2 │ │ ├── objective-c-B1aVtJYH.js.gz │ │ ├── papaparse.min-CTJG8ke1.js.gz │ │ ├── placeholder-Ce440-tv.js.gz │ │ ├── systemverilog-DgMryOEJ.js.gz │ │ ├── DropDownButton-CqCPOTsc.js.gz │ │ ├── InputDateRange-PxuYfEfI.js.gz │ │ ├── InputMonthRange-nwM7f3hr.js.gz │ │ ├── InputSignature-B7n3LFnL.js.gz │ │ ├── InputYearRange-hjSYvO0Y.js.gz │ │ ├── LocationPicker-DBYfbV_8.js.gz │ │ ├── SwitchContainer-3yEgmLyV.js.gz │ │ ├── TooltipWrapper-ChLuieoV.js.gz │ │ ├── TransferPicker-DqhUaEnj.js.gz │ │ ├── fa-regular-400-Cy4iLbxs.woff2 │ │ ├── ConditionBuilder-CFnviUkg.js.gz │ │ ├── InputQuarterRange-Bum1jEc2.js.gz │ │ ├── JSONSchemaEditor-B2Y_oqnh.js.gz │ │ ├── MatrixCheckboxes-5siVion2.js.gz │ │ ├── PaginationWrapper-D-69aPye.js.gz │ │ ├── TabsTransferPicker-q0hkZ6ww.js.gz │ │ ├── echarts-wordcloud-D_C6X7sB.js.gz │ │ ├── fa-v4compatibility-B9t6EWrS.woff2 │ │ ├── fa-v4compatibility-ch80hpM0.ttf │ │ ├── react-cropper.es-MCaA4dkC.js.gz │ │ ├── restructuredtext-CghPJEOS.js.gz │ │ ├── InputVerificationCode-BgRKI8ob.js.gz │ │ ├── ButtonGroup-DyCu1PoZ.js │ │ ├── Calendar-CpZqCV21.js │ │ ├── Hidden-DpmgexR4.js │ │ ├── omitBy-CdFgv6uo.js │ │ ├── AMIS-BUG0ZLGD.js │ │ ├── codemirror-4hOELPTM.js │ │ ├── javascript-CssWoUFW.js │ │ ├── MultilineText-BpC-L8JY.js │ │ ├── UUID-CcjQuoEW.js │ │ ├── Spinner-Cmqig17H.js │ │ ├── Alert--owwxmdX.js │ │ ├── WebComponent-_WejfBU5.js │ │ ├── azcli-1IWB1ccx.js │ │ ├── Shape-DIqVKXes.js │ │ ├── Color-BYPpAl8W.js │ │ ├── index-BK_OBolq.js │ │ ├── ButtonToolbar-D4LSHIid.js │ │ ├── Control-C0YoRP25.js │ │ ├── javascript-DvxtvP1Q.js │ │ ├── Operation-BpnWeiA_.js │ │ ├── index-JZf0XtWs.js │ │ ├── InputArray-C-FIO9Li.js │ │ ├── Breadcrumb-COapvxbD.js │ │ ├── Wrapper-D4hYo5aZ.js │ │ ├── BarCode-BlW6OpNb.js │ │ ├── VBox-HiUdzAG-.js │ │ ├── ini-BvajGCUy.js │ │ ├── JSONSchema-BTUn0wAK.js │ │ ├── SparkLine-Dv5W1vFp.js │ │ ├── Password-y2UY9u3i.js │ │ ├── DateRange-CReX7c1E.js │ │ ├── Link-B5v7OQvd.js │ │ ├── GridNav-Ck4ekt-U.js │ │ ├── PaginationWrapper-D-69aPye.js │ │ ├── csp-C46ZqvIl.js │ │ ├── InputColor-B1H9OsY3.js │ │ ├── Number-BUnbYTq2.js │ │ ├── JSONSchemaEditor-B2Y_oqnh.js │ │ ├── Pagination-7hQWoF5V.js │ │ ├── InputVerificationCode-BgRKI8ob.js │ │ ├── pla-CjnFlu4u.js │ │ ├── scheme-Dhb-2j9p.js │ │ ├── Plain-D0Ub5Iv4.js │ │ ├── InputMonthRange-nwM7f3hr.js │ │ ├── InputYearRange-hjSYvO0Y.js │ │ └── flow9-Cac8vKd7.js │ ├── logo.png │ ├── default-avatar.png │ ├── scripts │ │ └── loading.js.gz │ └── index.html ├── public │ ├── logo.png │ └── default-avatar.png ├── postcss.config.js ├── README.md ├── install-amis.sh ├── .env ├── tailwind.config.js ├── index.html ├── .gitignore ├── .eslintrc ├── tsconfig.json └── vite.config.ts ├── src ├── Console │ ├── stubs │ │ ├── bootstrap.stub │ │ ├── AuthController.stub │ │ └── routes.stub │ ├── Module │ │ └── stubs │ │ │ ├── bootstrap.stub │ │ │ ├── AdminMenu.stub │ │ │ ├── AuthController.stub │ │ │ ├── ServiceProvider.stub │ │ │ ├── AdminUser.stub │ │ │ ├── AdminPermission.stub │ │ │ ├── AdminRole.stub │ │ │ └── routes.stub │ └── CreateUserCommand.php ├── Extend │ └── stubs │ │ ├── README.md.stub │ │ ├── .gitignore.stub │ │ ├── routes.stub │ │ ├── controller.stub │ │ ├── extension.stub │ │ └── composer.json.stub ├── Support │ ├── Facon-2.ttf │ ├── Apis │ │ ├── AdminApiInterface.php │ │ ├── SaveSettingsApi.php │ │ ├── DataListApi.php │ │ ├── DataDetailApi.php │ │ ├── DataCreateApi.php │ │ ├── OptionsApi.php │ │ ├── GetSettingsApi.php │ │ ├── DataDeleteApi.php │ │ └── DataUpdateApi.php │ ├── Pipeline.php │ ├── CodeGenerator │ │ ├── stubs │ │ │ └── migration.stub │ │ └── RouteGenerator.php │ └── Cores │ │ ├── Relationships.php │ │ └── Api.php ├── Traits │ ├── MakeTrait.php │ ├── DatetimeFormatterTrait.php │ ├── ErrorTrait.php │ └── CheckActionTrait.php ├── Renderers │ ├── Button.php │ ├── Html.php │ ├── Component.php │ ├── TableView.php │ ├── IconItem.php │ ├── AutoFillHeight.php │ ├── RowSelectionOptions.php │ ├── Barcode.php │ ├── IconChecked.php │ ├── SvgIcon.php │ ├── SchemaCopyable.php │ ├── WebComponent.php │ ├── SchemaMessage.php │ ├── ChartRadios.php │ ├── ComboCondition.php │ ├── ConditionGroupValue.php │ ├── QRCodeImageSettings.php │ ├── AutoGenerateFilter.php │ ├── Markdown.php │ ├── Expandable.php │ └── ImageToolbarAction.php ├── Models │ ├── AdminPage.php │ ├── AdminCodeGenerator.php │ ├── AdminSetting.php │ ├── BaseModel.php │ ├── AdminRole.php │ ├── Extension.php │ ├── AdminMenu.php │ ├── PersonalAccessToken.php │ └── AdminApi.php ├── Events │ └── ExtensionChanged.php ├── Middleware │ ├── Bootstrap.php │ ├── AutoSetLocale.php │ ├── Permission.php │ └── Authenticate.php ├── Exceptions │ └── AdminException.php └── Controllers │ └── AdminApiController.php ├── .gitattributes ├── .phpstorm.meta.php ├── lang ├── zh_CN │ └── menu.php └── en │ └── menu.php ├── database └── migrations │ └── 2022_08_22_203040_install_owl_admin.php ├── CONTRIBUTING.md ├── LICENSE └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /admin-views/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /src/Console/stubs/bootstrap.stub: -------------------------------------------------------------------------------- 1 | 5 | 6 | export default AmisLogin 7 | -------------------------------------------------------------------------------- /src/Extend/stubs/routes.stub: -------------------------------------------------------------------------------- 1 | " 5 | exit 1 6 | fi 7 | 8 | pnpm i amis@$1 amis-core@$1 amis-editor@$1 amis-editor-core@$1 amis-ui@$1 9 | -------------------------------------------------------------------------------- /admin-views/src/service/request/index.ts: -------------------------------------------------------------------------------- 1 | import CustomAxiosInstance from "@/service/request/instance" 2 | import config from "./config" 3 | 4 | export const request = new CustomAxiosInstance(config).instance 5 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/AdminMenu.stub: -------------------------------------------------------------------------------- 1 | { 5 | return useSize(document.body)?.width < 768 6 | } 7 | 8 | export default useSmallScreen 9 | -------------------------------------------------------------------------------- /src/Traits/MakeTrait.php: -------------------------------------------------------------------------------- 1 | Button 按钮
7 | * 8 | * @link https://aisuda.bce.baidu.com/amis/zh-CN/components/button 9 | */ 10 | class Button extends VanillaAction 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /admin-views/dist/assets/ButtonGroup-DyCu1PoZ.js: -------------------------------------------------------------------------------- 1 | import{t as e,D as n,E as o,a1 as u}from"./index-CEmnTf-r.js";var p=function(r){e(t,r);function t(){return r!==null&&r.apply(this,arguments)||this}return t=n([o({type:"button-group"})],t),t}(u);export{p as ButtonGroupRenderer,u as default}; 2 | -------------------------------------------------------------------------------- /src/Renderers/Html.php: -------------------------------------------------------------------------------- 1 | Html
7 | * 8 | * @link https://aisuda.bce.baidu.com/amis/zh-CN/components/html 9 | */ 10 | class Html extends Tpl 11 | { 12 | public string $type = 'html'; 13 | } 14 | -------------------------------------------------------------------------------- /admin-views/src/components/AmisRender/CustomComponents/components/SvgIcon/index.tsx: -------------------------------------------------------------------------------- 1 | import React, {forwardRef} from "react" 2 | import {Icon} from "@iconify/react" 3 | 4 | const SvgIcon = forwardRef((props: any, ref) => ) 5 | 6 | export default SvgIcon 7 | -------------------------------------------------------------------------------- /.phpstorm.meta.php: -------------------------------------------------------------------------------- 1 | 'json', 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /lang/zh_CN/menu.php: -------------------------------------------------------------------------------- 1 | '控制台', 5 | 'admin_system' => '系统管理', 6 | 'admin_users' => '管理员', 7 | 'admin_roles' => '角色', 8 | 'admin_permission' => '权限', 9 | 'admin_menu' => '菜单', 10 | 'admin_setting' => '设置', 11 | ]; 12 | -------------------------------------------------------------------------------- /lang/en/menu.php: -------------------------------------------------------------------------------- 1 | 'Dashboard', 5 | 'admin_system' => 'Admin', 6 | 'admin_users' => 'Users', 7 | 'admin_roles' => 'Roles', 8 | 'admin_permission' => 'Permissions', 9 | 'admin_menu' => 'Menus', 10 | 'admin_setting' => 'Settings', 11 | ]; 12 | -------------------------------------------------------------------------------- /admin-views/src/context.tsx: -------------------------------------------------------------------------------- 1 | import {createContext} from 'react' 2 | 3 | export const GlobalContext = createContext<{ 4 | lang?: string; 5 | setLang?: (value: string) => void; 6 | theme?: string; 7 | setTheme?: (value: string) => void; 8 | antdToken?: {}; 9 | setAntdToken?: (value: any) => void; 10 | }>({}) 11 | -------------------------------------------------------------------------------- /src/Events/ExtensionChanged.php: -------------------------------------------------------------------------------- 1 | format($this->getDateFormat()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Calendar-CpZqCV21.js: -------------------------------------------------------------------------------- 1 | import{t as n,z as t,D as d,E as o}from"./index-CEmnTf-r.js";import{DateControlRenderer as a}from"./InputDate-BRQWnCdy.js";var i=function(r){n(e,r);function e(){return r!==null&&r.apply(this,arguments)||this}return e.defaultProps=t(t({},a.defaultProps),{embed:!0}),e=d([o({type:"calendar"})],e),e}(a);export{i as CalendarRenderer}; 2 | -------------------------------------------------------------------------------- /src/Middleware/Bootstrap.php: -------------------------------------------------------------------------------- 1 | load(loader, {}); 13 | -------------------------------------------------------------------------------- /src/Support/Apis/AdminApiInterface.php: -------------------------------------------------------------------------------- 1 | { 4 | const state: any = useSelector((state: GlobalState) => state) 5 | const dispatch = useDispatch() 6 | const getState = () => state 7 | 8 | return { 9 | state, 10 | getState, 11 | dispatch 12 | } 13 | } 14 | 15 | export default useStore 16 | -------------------------------------------------------------------------------- /src/Extend/stubs/controller.stub: -------------------------------------------------------------------------------- 1 | basePage()->body('{className} Extension.'); 12 | 13 | return $this->response()->success($page); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Middleware/AutoSetLocale.php: -------------------------------------------------------------------------------- 1 | header('locale', config('app.locale')); 13 | App::setLocale($locale); 14 | return $next($request); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /admin-views/src/components/AmisRender/CustomComponents/components/Watermark/index.tsx: -------------------------------------------------------------------------------- 1 | import React, {forwardRef} from 'react' 2 | import {WatermarkProps} from 'antd' 3 | import {Watermark as AntdWatermark} from 'antd' 4 | 5 | const Watermark = forwardRef((props: WatermarkProps | any, ref) => 6 | {props.body ? props.render('body', props.body, {}) : null}) 7 | 8 | export default Watermark 9 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Hidden-DpmgexR4.js: -------------------------------------------------------------------------------- 1 | import{t as e,l as r,D as o,a2 as a}from"./index-CEmnTf-r.js";var l=function(t){e(n,t);function n(){return t!==null&&t.apply(this,arguments)||this}return n.prototype.render=function(){return null},n}(r.Component),i=function(t){e(n,t);function n(){return t!==null&&t.apply(this,arguments)||this}return n=o([a({type:"hidden",wrap:!1,sizeMutable:!1})],n),n}(l);export{i as HiddenControlRenderer,l as default}; 2 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/ServiceProvider.stub: -------------------------------------------------------------------------------- 1 | loadMigrationsFrom(__DIR__ . '/../database/migrations'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Models/AdminCodeGenerator.php: -------------------------------------------------------------------------------- 1 | 'array', 13 | 'needs' => 'array', 14 | 'menu_info' => 'array', 15 | 'page_info' => 'array', 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /src/Renderers/Component.php: -------------------------------------------------------------------------------- 1 | 9 | * 使用setType(), 设置组件类型
10 | * 组件的其余属性可以直接调用对应属性名的方法如: ->value($value), 会有__call()来实现该方法
11 | * 也可以使用set(属性名, 属性值)方法来设置组件的属性
12 | */ 13 | class Component extends BaseRenderer 14 | { 15 | public function setType($type) 16 | { 17 | return $this->set('type', $type); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/AdminUser.stub: -------------------------------------------------------------------------------- 1 | belongsToMany(AdminRole::class, '{{module}}_admin_role_users', 'user_id', 'role_id')->withTimestamps(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Extend/stubs/extension.stub: -------------------------------------------------------------------------------- 1 | baseSettingForm()->body([ 15 | TextControl::make()->name('value')->label('Value')->required(true), 16 | ]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /admin-views/dist/assets/omitBy-CdFgv6uo.js: -------------------------------------------------------------------------------- 1 | import{g as a,aW as e,aX as n}from"./index-CEmnTf-r.js";var s="Expected a function";function o(r){if(typeof r!="function")throw new TypeError(s);return function(){var t=arguments;switch(t.length){case 0:return!r.call(this);case 1:return!r.call(this,t[0]);case 2:return!r.call(this,t[0],t[1]);case 3:return!r.call(this,t[0],t[1],t[2])}return!r.apply(this,t)}}var u=o,c=e,i=u,l=n;function f(r,t){return l(r,i(c(t)))}var g=f;const y=a(g);export{y as o}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/AMIS-BUG0ZLGD.js: -------------------------------------------------------------------------------- 1 | import{t as i,aq as u,D as l,E as c,l as m}from"./index-CEmnTf-r.js";var f=function(t){i(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.render=function(){var a=this.props,n=a.render,s=a.props,o=a.schema,r=u(this.props)||o;if(typeof r=="string")try{r=JSON.parse(r)}catch(p){console.warn("amis value must be json string",p),r=null}return n("amis",r,s)},e=l([c({type:"amis"})],e),e}(m.Component);export{f as AMISRenderer}; 2 | -------------------------------------------------------------------------------- /src/Support/Pipeline.php: -------------------------------------------------------------------------------- 1 | send($passable); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /admin-views/src/hooks/useSetting.ts: -------------------------------------------------------------------------------- 1 | import {useSelector} from 'react-redux' 2 | import {arrayGet} from '@/utils/common' 3 | 4 | // 设置 5 | const useSetting = () => { 6 | // 从 redux 中获取设置 7 | const settings: any = useSelector((state: GlobalState) => state.settings) 8 | 9 | // 获取设置 10 | const getSetting = (key = '', def = '') => { 11 | return key ? arrayGet(settings, key, def) : settings 12 | } 13 | 14 | return {settings, getSetting} 15 | } 16 | 17 | export default useSetting 18 | -------------------------------------------------------------------------------- /admin-views/src/service/request/config.ts: -------------------------------------------------------------------------------- 1 | import {AxiosRequestConfig} from "axios" 2 | 3 | interface RequestConfig extends AxiosRequestConfig { 4 | // 代理路径 5 | proxyURL: string, 6 | // 是否跨域 7 | changeOrigin: boolean, 8 | } 9 | 10 | export default { 11 | // @ts-ignore 12 | baseURL: window.$adminApiPrefix || import.meta.env.VITE_API_PREFIX, 13 | proxyURL: import.meta.env.VITE_PROXY_URL, 14 | changeOrigin: import.meta.env.VITE_PROXY_CHANGE_ORIGIN === "Y", 15 | } 16 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/IconButton/index.tsx: -------------------------------------------------------------------------------- 1 | import {Icon} from '@iconify/react' 2 | 3 | // 图标按钮 4 | const IconButton = ({onClick, icon = null, children = null, iconClassName = ''}) => { 5 | return ( 6 |
8 | {children ? children : } 9 |
10 | ) 11 | } 12 | export default IconButton 13 | -------------------------------------------------------------------------------- /src/Middleware/Permission.php: -------------------------------------------------------------------------------- 1 | permissionIntercept($request, $args)) { 14 | return Admin::response()->fail(admin_trans('admin.unauthorized')); 15 | } 16 | 17 | return $next($request); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /admin-views/dist/assets/codemirror-4hOELPTM.js: -------------------------------------------------------------------------------- 1 | import{g as a}from"./index-CEmnTf-r.js";import{r as f}from"./codemirror-CNCHanJM.js";function s(o,c){for(var t=0;tr[e]})}}}return Object.freeze(Object.defineProperty(o,Symbol.toStringTag,{value:"Module"}))}var n=f();const m=a(n),d=s({__proto__:null,default:m},[n]);export{d as c}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/javascript-CssWoUFW.js: -------------------------------------------------------------------------------- 1 | import{g as c}from"./index-CEmnTf-r.js";import{r as n}from"./javascript-CvYo9acX.js";function p(t,s){for(var o=0;or[e]})}}}return Object.freeze(Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}))}var i=n();const f=c(i),l=p({__proto__:null,default:f},[i]);export{l as j}; 2 | -------------------------------------------------------------------------------- /admin-views/src/utils/proxy.ts: -------------------------------------------------------------------------------- 1 | import type {ProxyOptions} from "vite" 2 | 3 | /** 4 | * 设置网络代理 5 | */ 6 | export function createViteProxy(env) { 7 | if (env.PROD) return undefined 8 | if (env.VITE_PROXY_CHANGE_ORIGIN !== "Y") return undefined 9 | 10 | const proxy: Record = { 11 | [env.VITE_API_PREFIX]: { 12 | target: env.VITE_PROXY_URL, 13 | changeOrigin: env.VITE_PROXY_CHANGE_ORIGIN === "Y", 14 | }, 15 | } 16 | 17 | return proxy 18 | } 19 | -------------------------------------------------------------------------------- /admin-views/src/hooks/useLang.ts: -------------------------------------------------------------------------------- 1 | import zh_CN from '@/lang/zh_CN' 2 | import en from '@/lang/en' 3 | import useSetting from '@/hooks/useSetting' 4 | import {arrayGet} from '@/utils/common' 5 | 6 | // 多语言 7 | export const useLang = () => { 8 | const {getSetting} = useSetting() 9 | const lang = {zh_CN, en} 10 | 11 | const t = (key: string) => { 12 | const locale = getSetting('locale', 'zh_CN') 13 | 14 | return arrayGet(lang[locale], key, key) 15 | } 16 | 17 | return { 18 | t 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/AdminPermission.stub: -------------------------------------------------------------------------------- 1 | belongsToMany(AdminMenu::class, '{{module}}_admin_permission_menu', 'permission_id', 'menu_id') 14 | ->withTimestamps(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Models/AdminSetting.php: -------------------------------------------------------------------------------- 1 | 'json', 15 | ]; 16 | 17 | protected function asJson($value, $flags = 0) 18 | { 19 | return json_encode($value, $flags == 0 ? JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES : $flags); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Renderers/TableView.php: -------------------------------------------------------------------------------- 1 | set('type', 'table-view'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 指定为 table-view 渲染器。 22 | */ 23 | public function type($value = 'table-view') 24 | { 25 | return $this->set('type', $value); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /admin-views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /admin-views/src/pages/404/index.tsx: -------------------------------------------------------------------------------- 1 | import {Button, Result} from 'antd' 2 | import {useLang} from '@/hooks/useLang' 3 | import {useHistory} from 'react-router' 4 | 5 | const NotFound = () => { 6 | const {t} = useLang() 7 | const history = useHistory() 8 | 9 | return ( history.replace('/')}>{t('not_found.back_home')}} 14 | />) 15 | } 16 | 17 | export default NotFound 18 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/AdminRole.stub: -------------------------------------------------------------------------------- 1 | belongsToMany(AdminPermission::class, '{{module}}_admin_role_permissions', 'role_id', 'permission_id') 14 | ->withTimestamps(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/LayoutTopBar/components/FullscreenButton/index.tsx: -------------------------------------------------------------------------------- 1 | import {useFullscreen} from 'ahooks' 2 | import IconButton from '@/layouts/components/IconButton' 3 | 4 | const FullscreenButton = () => { 5 | const [isFullscreen, {toggleFullscreen}] = useFullscreen(document.getElementById('root')) 6 | 7 | return ( 8 | toggleFullscreen()}/> 10 | ) 11 | } 12 | 13 | export default FullscreenButton 14 | -------------------------------------------------------------------------------- /src/Models/BaseModel.php: -------------------------------------------------------------------------------- 1 | connection)){ 16 | $this->setConnection(Admin::config('admin.database.connection')); 17 | } 18 | 19 | parent::__construct($attributes); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Console/stubs/routes.stub: -------------------------------------------------------------------------------- 1 | \Slowlyo\OwlAdmin\Admin::view()); 7 | 8 | Route::group([ 9 | 'domain' => config('admin.route.domain'), 10 | 'prefix' => config('admin.route.prefix'), 11 | 'middleware' => config('admin.route.middleware'), 12 | ], function (Router $router) { 13 | $router->resource('dashboard', \{{Namespace}}\HomeController::class); 14 | $router->resource('system/settings', \{{Namespace}}\SettingController::class); 15 | }); 16 | -------------------------------------------------------------------------------- /admin-views/dist/assets/MultilineText-BpC-L8JY.js: -------------------------------------------------------------------------------- 1 | import{t as r,aq as a,l as i,ei as u,z as o,D as s,E as d,L as x}from"./index-CEmnTf-r.js";var f=function(e){r(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.render=function(){var l=a(this.props,function(n){return n.text?x(n.text,n.data,"| raw"):void 0});return i.createElement(u,o({},this.props,{text:l}))},t}(i.Component),m=function(e){r(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t=s([d({type:"multiline-text"})],t),t}(f);export{f as MultilineTextField,m as MultilineTextFieldRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/LayoutFooter/index.tsx: -------------------------------------------------------------------------------- 1 | import useSettings from '@/hooks/useSetting' 2 | 3 | // 页脚 4 | const LayoutFooter = () => { 5 | const {getSetting} = useSettings() 6 | 7 | if(!getSetting('system_theme_setting.footer')){ 8 | return null 9 | } 10 | 11 | return ( 12 |
13 |
14 |
15 | ) 16 | } 17 | 18 | export default LayoutFooter 19 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/LayoutTopBar/components/SettingButton/index.tsx: -------------------------------------------------------------------------------- 1 | import IconButton from '@/layouts/components/IconButton' 2 | import useStore from '@/hooks/useStore' 3 | 4 | const SettingButton = () => { 5 | const {state, dispatch} = useStore() 6 | const toggle = () => { 7 | dispatch({ 8 | type: 'update-open-setting', 9 | payload: {openSetting: !state.openSetting} 10 | }) 11 | } 12 | 13 | return ( 14 | 15 | ) 16 | } 17 | 18 | export default SettingButton 19 | -------------------------------------------------------------------------------- /admin-views/src/service/api/auth.ts: -------------------------------------------------------------------------------- 1 | import {request} from '../request'; 2 | 3 | /** 4 | * 登录 5 | * @param data - 登录数据 6 | */ 7 | export const fetchLogin = (data: any) => request.post('/login', data); 8 | 9 | /** 10 | * 获取用户信息 11 | */ 12 | export const fetchUserInfo = () => request.get('/current-user'); 13 | 14 | /** 15 | * 获取用户路由数据 16 | */ 17 | export const fetchUserRoutes = () => request.get('/menus') 18 | 19 | /** 20 | * 登出 21 | */ 22 | export const fetchLogout = () => request.get('/logout') 23 | 24 | /** 25 | * 获取验证码 26 | */ 27 | export const fetchCaptcha = () => request.get('/captcha'); 28 | -------------------------------------------------------------------------------- /database/migrations/2022_08_22_203040_install_owl_admin.php: -------------------------------------------------------------------------------- 1 | up(); 14 | } 15 | 16 | /** 17 | * Reverse the migrations. 18 | * 19 | * @return void 20 | */ 21 | public function down(): void 22 | { 23 | \Slowlyo\OwlAdmin\Support\Cores\Database::make()->down(); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /admin-views/dist/assets/UUID-CcjQuoEW.js: -------------------------------------------------------------------------------- 1 | import{t as o,cf as a,l as u,D as i,a2 as l}from"./index-CEmnTf-r.js";var s=function(n){o(t,n);function t(e){var r=n.call(this,e)||this;return e.value||r.setValue(),r}return t.prototype.componentDidUpdate=function(e){!e.value&&e.formInited!==!1&&this.setValue()},t.prototype.setValue=function(){var e=this.props,r=a();e.length&&(r=r.substring(0,e.length)),e.onChange(r)},t.prototype.render=function(){return null},t}(u.Component),d=function(n){o(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t=i([l({type:"uuid",wrap:!1,sizeMutable:!1})],t),t}(s);export{d as UUIDControlRenderer,s as default}; 2 | -------------------------------------------------------------------------------- /src/Renderers/IconItem.php: -------------------------------------------------------------------------------- 1 | set('icon', $value); 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | public function position($value = '') 31 | { 32 | return $this->set('position', $value); 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Spinner-Cmqig17H.js: -------------------------------------------------------------------------------- 1 | import{t as l,v as c,l as a,P as p,z as d,D as m,E as y}from"./index-CEmnTf-r.js";var _=function(s){l(r,s);function r(){return s!==null&&s.apply(this,arguments)||this}return r.prototype.renderBody=function(){var e=this.props,n=e.body,t=e.render;return n?t("body",n):null},r.prototype.render=function(){var e=this.props,n=e.classnames,t=e.spinnerWrapClassName,i=e.body,o=c(e,["classnames","spinnerWrapClassName","body"]);return i?a.createElement("div",{className:n("Spinner-wrap",t)},a.createElement(p,d({},o)),this.renderBody()):a.createElement(p,d({},o))},r=m([y({type:"spinner"})],r),r}(a.Component);export{_ as SpinnerRenderer}; 2 | -------------------------------------------------------------------------------- /src/Renderers/AutoFillHeight.php: -------------------------------------------------------------------------------- 1 | set('height', $value); 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | public function maxHeight($value = '') 31 | { 32 | return $this->set('maxHeight', $value); 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/LayoutTopBar/components/RefreshButton/index.tsx: -------------------------------------------------------------------------------- 1 | import {useState} from 'react' 2 | import IconButton from '@/layouts/components/IconButton' 3 | 4 | const RefreshButton = () => { 5 | const [refreshing, setRefreshing] = useState(false) 6 | 7 | return ( 8 | { 9 | setRefreshing(true) 10 | window.$owl.refreshAmisPage().then(() => { 11 | setTimeout(() => setRefreshing(false), 500) 12 | }) 13 | }}/> 14 | ) 15 | } 16 | export default RefreshButton 17 | -------------------------------------------------------------------------------- /src/Renderers/RowSelectionOptions.php: -------------------------------------------------------------------------------- 1 | set('key', $value); 25 | } 26 | 27 | /** 28 | * 选项显示文本 29 | */ 30 | public function text($value = '') 31 | { 32 | return $this->set('text', $value); 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/CollapseTrigger/index.tsx: -------------------------------------------------------------------------------- 1 | import {Icon} from '@iconify/react' 2 | import IconButton from '@/layouts/components/IconButton' 3 | 4 | // 折叠切换按钮 5 | const CollapseTrigger = ({collapsed, toggle}) => { 6 | return ( 7 | toggle(!collapsed)}> 8 |
9 | {collapsed && } 10 | {collapsed || } 11 |
12 |
13 | ) 14 | } 15 | 16 | export default CollapseTrigger 17 | -------------------------------------------------------------------------------- /admin-views/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # typescript 37 | *.tsbuildinfo 38 | 39 | 40 | # eslint 41 | .eslintcache 42 | 43 | # stylelint 44 | .stylelintcache -------------------------------------------------------------------------------- /admin-views/dist/assets/Alert--owwxmdX.js: -------------------------------------------------------------------------------- 1 | import{t as v,v as _,w as i,x as l,l as c,y as f,z as y,D as m,E as b}from"./index-CEmnTf-r.js";var A=function(s){v(r,s);function r(){return s!==null&&s.apply(this,arguments)||this}return r.prototype.render=function(){var e=this.props,d=e.render,p=e.body,t=e.level,n=e.icon,a=e.showIcon,o=e.actions,h=_(e,["render","body","level","icon","showIcon","actions"]);i(t)&&(t=l(t,this.props.data)),i(n)&&(n=l(n,this.props.data)),i(a)&&(a=l(a,this.props.data));var u=o?c.isValidElement(o)?o:d("alert-actions",o):null;return c.createElement(f,y({},h,{level:t,icon:n,showIcon:a,actions:u}),d("body",p))},r=m([b({type:"alert"})],r),r}(c.Component);export{A as AlertRenderer}; 2 | -------------------------------------------------------------------------------- /src/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | authIntercept($request)) { 14 | return Admin::response() 15 | ->additional(['code' => Response::HTTP_UNAUTHORIZED]) 16 | ->doNotDisplayToast() 17 | ->fail(admin_trans('admin.please_login')); 18 | } 19 | 20 | Admin::permission()->checkUserStatus(); 21 | 22 | return $next($request); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Console/Module/stubs/routes.stub: -------------------------------------------------------------------------------- 1 | \Slowlyo\OwlAdmin\Admin::view(config('{{module}}.admin.route.prefix'))); 7 | 8 | Route::group([ 9 | 'as' => '{{module}}', 10 | 'domain' => config('{{module}}.admin.route.domain'), 11 | 'prefix' => config('{{module}}.admin.route.prefix'), 12 | 'middleware' => config('{{module}}.admin.route.middleware'), 13 | ], function (Router $router) { 14 | $router->resource('dashboard', \{{Namespace}}\HomeController::class); 15 | $router->resource('system/settings', \{{Namespace}}\SettingController::class); 16 | }); 17 | -------------------------------------------------------------------------------- /admin-views/dist/assets/WebComponent-_WejfBU5.js: -------------------------------------------------------------------------------- 1 | import{t as s,dk as y,x as m,l as p,z as f,D as c,E as b}from"./index-CEmnTf-r.js";var v=function(t){s(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.renderBody=function(){var n=this.props,r=n.body,a=n.render;return r?a("body",r):null},e.prototype.render=function(){var n=this.props,r=n.tag,a=n.props,d=n.data,i=n.style,l=y(a,function(o){return typeof o=="string"&&m(o,d,"| raw")||o}),u=r||"div";return p.createElement(u,f({},l,{style:i}),this.renderBody())},e}(p.Component),g=function(t){s(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e=c([b({type:"web-component"})],e),e}(v);export{g as WebComponentRenderer,v as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Support/CodeGenerator/stubs/migration.stub: -------------------------------------------------------------------------------- 1 | { 8 | // 图标 iconify 9 | Renderer({type: 'custom-svg-icon', autoVar: true})(SvgIcon) 10 | // 富文本编辑器 wangEditor 11 | FormItem({type: 'custom-wang-editor', autoVar: true})(WangEditor) 12 | // 水印 Watermark 13 | Renderer({type: 'custom-watermark', autoVar: true})(Watermark) 14 | // editor 15 | FormItem({type: 'custom-amis-editor', autoVar: true})(SchemaEditor) 16 | } 17 | -------------------------------------------------------------------------------- /src/Support/Apis/SaveSettingsApi.php: -------------------------------------------------------------------------------- 1 | adminSetMany(request()->all()); 17 | } 18 | 19 | public function argsSchema() 20 | { 21 | return [ 22 | amis()->Markdown()->value('### 使用说明 23 | 24 | - 接口请求方式为 `POST` 25 | - 请求参数为数组格式 (将该api作为表单的提交api即可正常使用) 26 | 27 | ```JSON 28 | { 29 | "site_name": "string", 30 | "name": "string", 31 | "age": 0 32 | } 33 | ```'), 34 | ]; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Renderers/Barcode.php: -------------------------------------------------------------------------------- 1 | set('type', 'barcode'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 外层类名 22 | */ 23 | public function className($value = '') 24 | { 25 | return $this->set('className', $value); 26 | } 27 | 28 | /** 29 | * 指定为 barcode 渲染器。 30 | */ 31 | public function type($value = 'barcode') 32 | { 33 | return $this->set('type', $value); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Shape-DIqVKXes.js: -------------------------------------------------------------------------------- 1 | import{t as y,v as m,L as i,l as d,bh as _,z as f,ag as v,D as l,Q as g,T as t,E as T}from"./index-CEmnTf-r.js";var C=function(s){y(a,s);function a(){return s!==null&&s.apply(this,arguments)||this}return a.prototype.handleClick=function(){this.props.dispatchEvent("click",this.props.data)},a.prototype.render=function(){var e=this.props,o=e.className,r=e.radius,n=e.shapeType,p=e.data,c=m(e,["className","radius","shapeType","data"]),h=i(n,p)||n,u=+i(r,p)||r;return d.createElement(_,f({},c,{className:v(o),shapeType:h,radius:u,onClick:this.handleClick}))},l([g,t("design:type",Function),t("design:paramtypes",[]),t("design:returntype",void 0)],a.prototype,"handleClick",null),a=l([T({type:"shape"})],a),a}(d.Component);export{C as ShapeRenderer}; 2 | -------------------------------------------------------------------------------- /src/Exceptions/AdminException.php: -------------------------------------------------------------------------------- 1 | data = $data; 17 | $this->doNotDisplayToast = $doNotDisplayToast; 18 | } 19 | 20 | public function render() 21 | { 22 | return Admin::response()->doNotDisplayToast($this->doNotDisplayToast)->fail($this->getMessage(), $this->data); 23 | } 24 | 25 | public function report() 26 | { 27 | // not report 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Color-BYPpAl8W.js: -------------------------------------------------------------------------------- 1 | import{t as s,aq as d,l as r,D as m,E as p}from"./index-CEmnTf-r.js";var C=function(l){s(e,l);function e(){return l!==null&&l.apply(this,arguments)||this}return e.prototype.render=function(){var o=this.props,n=o.className,u=o.style,a=o.classnames,c=o.defaultColor,i=o.showValue,t=d(this.props)||c;return r.createElement("div",{className:a("ColorField",n),style:u},r.createElement("i",{className:a("ColorField-previewIcon"),style:{backgroundColor:t}}),i&&t?r.createElement("span",{className:a("ColorField-value")},t):null)},e.defaultProps={className:"",defaultColor:"",showValue:!0},e}(r.Component),h=function(l){s(e,l);function e(){return l!==null&&l.apply(this,arguments)||this}return e=m([p({type:"color"})],e),e}(C);export{C as ColorField,h as ColorFieldRenderer}; 2 | -------------------------------------------------------------------------------- /src/Renderers/IconChecked.php: -------------------------------------------------------------------------------- 1 | set('id', $value); 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | public function name($value = '') 31 | { 32 | return $this->set('name', $value); 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | public function svg($value = '') 39 | { 40 | return $this->set('svg', $value); 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /admin-views/dist/assets/index-BK_OBolq.js: -------------------------------------------------------------------------------- 1 | import{r as t,j as n,F as f,s as c}from"./index-CEmnTf-r.js";function h({currentRoute:o}){const[a,s]=t.useState(!0),r=t.useRef(null),d=()=>{var i;const e=((i=document.querySelector(".ant-layout-content.overflow-hidden"))==null?void 0:i.offsetTop)||65;return`${window.innerHeight-e}px`},l=()=>{r.current.src=o.iframe_url};return t.useEffect(()=>{l();const e=()=>{r.current.style.height=d()};return window.addEventListener("resize",e),e(),()=>{window.removeEventListener("resize",e)}},[o.iframe_url]),n(f,{children:n(c,{spinning:a,style:{minHeight:a?"500px":""},children:n("iframe",{className:"owl-iframe",ref:r,title:"Iframe Page",width:"100%",style:{border:"none",order:0,boxSizing:"border-box",overflow:"hidden",minHeight:"500px"},onLoad:()=>{s(!1)}})})})}export{h as default}; 2 | -------------------------------------------------------------------------------- /src/Controllers/AdminApiController.php: -------------------------------------------------------------------------------- 1 | path())->replace(Admin::config('admin.route.prefix'), '')->value(); 19 | $api = $this->service->getApiByPath($path); 20 | 21 | if (!$api) { 22 | return $this->response()->success(); 23 | } 24 | 25 | return app($api->template)->setApiRecord($api)->handle(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /admin-views/dist/assets/ButtonToolbar-D4LSHIid.js: -------------------------------------------------------------------------------- 1 | import{t as u,l as s,D as c,a2 as i}from"./index-CEmnTf-r.js";var p=function(n){u(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t.prototype.renderButtons=function(){var r=this.props,o=r.render;r.classPrefix;var e=r.buttons;return Array.isArray(e)?e.map(function(l,a){return o("button/".concat(a),l,{key:a})}):null},t.prototype.render=function(){var r=this.props;r.buttons;var o=r.className,e=r.classnames;return r.render,r.style,s.createElement("div",{className:e("ButtonToolbar",o)},this.renderButtons())},t.propsList=["buttons","className"],t}(s.Component),m=function(n){u(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t=c([i({type:"button-toolbar",strictMode:!1})],t),t}(p);export{m as ButtonToolbarRenderer,p as default}; 2 | -------------------------------------------------------------------------------- /admin-views/src/service/api/base.ts: -------------------------------------------------------------------------------- 1 | import {request} from '../request' 2 | 3 | /** 4 | * 初始化页面结构 5 | * @param path 6 | * @param pageSign 7 | */ 8 | export const initPageSchema = (path: string, pageSign?: string) => { 9 | if (pageSign) { 10 | return request.get('/page_schema?sign=' + pageSign) 11 | } 12 | 13 | return request.get(path) 14 | } 15 | 16 | /** 17 | * amis请求 18 | * @param url 19 | * @param method 20 | * @param data 21 | */ 22 | export const amisRequest = (url, method, data) => request[method](url, data) 23 | 24 | /** 25 | * 获取设置 26 | */ 27 | export const fetchSettings = () => request.get('/_settings') 28 | 29 | /** 30 | * 保存设置 31 | * @param data 格式:{key1: value1, key2: value2, ...} 32 | */ 33 | export const saveSettings = (data: any) => request.post('/_settings', data) 34 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Control-C0YoRP25.js: -------------------------------------------------------------------------------- 1 | import{t as p,bi as u,v as m,l as s,bj as _,z as b,D as i,Q as c,T as l,E as f}from"./index-CEmnTf-r.js";var v=function(o){p(r,o);function r(){return o!==null&&o.apply(this,arguments)||this}return r.prototype.renderInput=function(){var e=this.props,n=e.render,d=e.body,a=e.name,t=e.data;return n("inner",d,{value:typeof a=="string"?u(a,t):void 0})},r.prototype.render=function(){var e,n=this.props,d=n.render,a=n.label;n.control;var t=m(n,["render","label","control"]);return s.createElement(_,b({},t,{formMode:(e=t.mode)!==null&&e!==void 0?e:t.formMode,render:d,sizeMutable:!1,label:a,renderControl:this.renderInput}))},i([c,l("design:type",Function),l("design:paramtypes",[]),l("design:returntype",void 0)],r.prototype,"renderInput",null),r=i([f({type:"control"})],r),r}(s.Component);export{v as ControlRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "browser": true, 5 | "commonjs": true, 6 | "es6": true, 7 | "node": true, 8 | "jest": true 9 | }, 10 | "parser": "@typescript-eslint/parser", 11 | "extends": [ 12 | "prettier", 13 | "plugin:@typescript-eslint/recommended", 14 | "plugin:react/recommended", 15 | "plugin:react-hooks/recommended" 16 | ], 17 | "parserOptions": { 18 | "ecmaFeatures": { 19 | "experimentalObjectRestSpread": true, 20 | "jsx": true 21 | }, 22 | "sourceType": "module" 23 | }, 24 | "settings": { 25 | "react": { 26 | "version": "16.8" 27 | } 28 | }, 29 | "plugins": ["react", "babel", "@typescript-eslint/eslint-plugin"], 30 | "rules": { 31 | "react/display-name": 0, 32 | "react/prop-types": 0 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /admin-views/dist/assets/javascript-DvxtvP1Q.js: -------------------------------------------------------------------------------- 1 | import{conf as t,language as e}from"./typescript-Dgyh4mcD.js";import"./editor.main-F140LpxE.js";import"./index-CEmnTf-r.js";var r=t,a={defaultToken:"invalid",tokenPostfix:".js",keywords:["break","case","catch","class","continue","const","constructor","debugger","default","delete","do","else","export","extends","false","finally","for","from","function","get","if","import","in","instanceof","let","new","null","return","set","super","switch","symbol","this","throw","true","try","typeof","undefined","var","void","while","with","yield","async","await","of"],typeKeywords:[],operators:e.operators,symbols:e.symbols,escapes:e.escapes,digits:e.digits,octaldigits:e.octaldigits,binarydigits:e.binarydigits,hexdigits:e.hexdigits,regexpctl:e.regexpctl,regexpesc:e.regexpesc,tokenizer:e.tokenizer};export{r as conf,a as language}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Operation-BpnWeiA_.js: -------------------------------------------------------------------------------- 1 | import{t as o,l as i,z as m,D as y,E as f}from"./index-CEmnTf-r.js";var v=function(t){o(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.render=function(){var n=this.props,d=n.className,c=n.style,s=n.buttons,p=n.render,u=n.classnames,a=n.testIdBuilder;return i.createElement("div",{className:u("OperationField",d),style:c},Array.isArray(s)?s.map(function(r,l){return p("".concat(l),m({type:"button",size:r.size||"sm",level:r.level||(r.icon&&!r.label?"link":"")},r),{key:l,testIdBuilder:a==null?void 0:a.getChild("button-".concat(r.testid||r.id||l))})}):null)},e.propsList=["buttons","label"],e.defaultProps={},e}(i.Component),F=function(t){o(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e=y([f({type:"operation"})],e),e}(v);export{v as OperationField,F as OperationFieldRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/index-JZf0XtWs.js: -------------------------------------------------------------------------------- 1 | import{h as r,l as t,n as i,j as e,o as n,S as h,A as m,p,q as u}from"./index-CEmnTf-r.js";const _=()=>{const{t:a}=r(),[s,l]=t.useState(!1),[o,c]=t.useState({}),d={type:"button",label:a("amis_editor.get_php_code"),level:"success",actionType:"ajax",api:{method:"post",url:"/dev_tools/editor_parse",data:{schema:o}},feedback:{title:"PHP Schema",size:"lg",body:{type:"editor",language:"php",name:"schema"}}};return i("div",{className:"h-screen",children:[e(n,{className:"h-full",title:a("amis_editor.editor"),bodyStyle:{padding:0,height:"calc(100% - 55px)"},extra:i(h,{children:[e(m,{schema:d}),e(p,{level:"primary",onClick:()=>l(!s),children:a(s?"amis_editor.edit":"amis_editor.preview")})]}),children:e("div",{className:"w-full h-full overflow-x-auto",children:e(u,{onChange:c,preview:s})})}),e("div",{className:"h-5"})]})};export{_ as default}; 2 | -------------------------------------------------------------------------------- /admin-views/src/layouts/components/LayoutTopBar/components/DarkThemeButton/index.tsx: -------------------------------------------------------------------------------- 1 | import IconButton from '@/layouts/components/IconButton' 2 | import useSetting from '@/hooks/useSetting' 3 | import useTheme from '@/hooks/useTheme' 4 | 5 | const DarkThemeButton = () => { 6 | const {getSetting} = useSetting() 7 | const {setDarkTheme} = useTheme() 8 | 9 | const toggleDarkTheme = () => { 10 | setDarkTheme(!getSetting('system_theme_setting.darkTheme')) 11 | } 12 | 13 | if (getSetting('system_theme_setting.followSystemTheme')) { 14 | return null 15 | } 16 | 17 | return ( 18 | toggleDarkTheme()}/> 20 | ) 21 | } 22 | 23 | export default DarkThemeButton 24 | -------------------------------------------------------------------------------- /admin-views/dist/assets/InputArray-C-FIO9Li.js: -------------------------------------------------------------------------------- 1 | import{t as a,v as c,l as n,z as m,D as f,a2 as u,cn as p}from"./index-CEmnTf-r.js";import d from"./Combo-DCjkjGTi.js";var y=function(o){a(r,o);function r(e){var t=o.call(this,e)||this;return t.comboRef=t.comboRef.bind(t),t}return r.prototype.comboRef=function(e){this.comboInstance=e},r.prototype.validate=function(e){return this.comboInstance?this.comboInstance.validate():null},r.prototype.render=function(){var e=this.props,t=e.items,s=e.scaffold,i=c(e,["items","scaffold"]),l=Array.isArray(t)?t.length>1?t.slice(0,1):t:t!=null?[t]:[];return n.createElement(d,m({},i,{scaffold:s,items:l,flat:!0,multiple:!0,multiLine:!1,ref:this.comboRef}))},r}(n.Component),_=function(o){a(r,o);function r(){return o!==null&&o.apply(this,arguments)||this}return r=f([u({type:"input-array",storeType:p.name})],r),r}(y);export{_ as ArrayControlRenderer,y as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Breadcrumb-COapvxbD.js: -------------------------------------------------------------------------------- 1 | import{t as d,v,x as u,L as o,l as c,a3 as p,z as _,D as m,E as B}from"./index-CEmnTf-r.js";var F=function(a){d(e,a);function e(){return a!==null&&a.apply(this,arguments)||this}return e.prototype.render=function(){var t=this.props,f=t.items,b=t.source,l=t.data,i=t.env,h=v(t,["items","source","data","env"]),s=f||u(b,l,"| raw");return s&&(s=s.map(function(r){return r.label&&(r.label=o(r.label,l)),r.href&&(r.href=u(r.href,l,"| raw")),r.dropdown&&(r.dropdown=r.dropdown.map(function(n){return n.label&&(n.label=o(n.label,l)),n.href&&(n.href=u(n.href,l,"| raw")),n})),r})),c.createElement(p,_({items:s,tooltipContainer:i==null?void 0:i.getModalContainer},h))},e}(c.Component),y=function(a){d(e,a);function e(){return a!==null&&a.apply(this,arguments)||this}return e=m([B({type:"breadcrumb"})],e),e}(F);export{F as BreadcrumbField,y as BreadcrumbFieldRenderer}; 2 | -------------------------------------------------------------------------------- /src/Renderers/SvgIcon.php: -------------------------------------------------------------------------------- 1 | set('type', 'custom-svg-icon'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 设置图标的类名 22 | */ 23 | public function className($value = '') 24 | { 25 | return $this->set('className', $value); 26 | } 27 | 28 | /** 29 | * 设置图标的名称 30 | */ 31 | public function icon($value = '') 32 | { 33 | return $this->set('icon', $value); 34 | } 35 | 36 | /** 37 | * 指定为 custom-svg-icon 渲染器。 38 | */ 39 | public function type($value = 'custom-svg-icon') 40 | { 41 | return $this->set('type', $value); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/Support/Cores/Relationships.php: -------------------------------------------------------------------------------- 1 | getAll(); 12 | 13 | if (blank($relationships)) { 14 | return; 15 | } 16 | 17 | foreach ($relationships as $relationship) { 18 | try { 19 | $relationship->model::resolveRelationUsing($relationship->title, function ($model) use ($relationship) { 20 | $method = $relationship->method; 21 | 22 | return $model->$method(...array_column($relationship->buildArgs(), 'value')); 23 | }); 24 | } catch (\Throwable $e) { 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /admin-views/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": false, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx", 22 | "baseUrl": ".", 23 | "paths": { 24 | "@/*": [ 25 | "src/*" 26 | ] 27 | } 28 | }, 29 | "include": [ 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Wrapper-D4hYo5aZ.js: -------------------------------------------------------------------------------- 1 | import{t as p,l as i,b6 as u,D as y,E as f}from"./index-CEmnTf-r.js";var m=function(a){p(r,a);function r(){return a!==null&&a.apply(this,arguments)||this}return r.prototype.renderBody=function(){var e=this.props,t=e.children,n=e.body,s=e.render,d=e.disabled;return t?typeof t=="function"?t(this.props):t:n?s("body",n,{disabled:d}):null},r.prototype.render=function(){var e=this.props,t=e.className,n=e.size,s=e.classnames,d=e.style,o=e.data,l=e.wrap,c=e.id;return l===!1?this.renderBody():i.createElement("div",{className:s("Wrapper",n&&n!=="none"?"Wrapper--".concat(n):"",t),style:u(d,o),"data-id":c},this.renderBody())},r.propsList=["body","className","children","size"],r.defaultProps={className:"",size:"md"},r}(i.Component),b=function(a){p(r,a);function r(){return a!==null&&a.apply(this,arguments)||this}return r=y([f({type:"wrapper"})],r),r}(m);export{b as WrapperRenderer,m as default}; 2 | -------------------------------------------------------------------------------- /src/Extend/stubs/composer.json.stub: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{package}", 3 | "alias": "{alias}", 4 | "description": "Description...", 5 | "type": "library", 6 | "version": "1.0.0", 7 | "keywords": ["owl-admin", "extension"], 8 | "homepage": "https://github.com/{package}", 9 | "license": "MIT", 10 | "authors": [ 11 | { 12 | "name": "your name", 13 | "email": "your email" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=8.0", 18 | "slowlyo/owl-admin": "*" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "{namespace}": "src/" 23 | } 24 | }, 25 | "extra": { 26 | "owl-admin": "{namespace}{className}ServiceProvider", 27 | "laravel": { 28 | "providers": [ 29 | "{namespace}{className}ServiceProvider" 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /admin-views/src/typeings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface Window { 4 | $adminApiPrefix: string; 5 | $owl: { 6 | logout: () => void, 7 | refreshRoutes: () => Promise, 8 | appLoader: () => void, 9 | afterLoginSuccess: (params: any, token: string) => void, 10 | refreshAmisPage: () => Promise, 11 | closeTabByPath: (path: string) => void, 12 | } 13 | } 14 | 15 | declare module "*.css" { 16 | const classes: { [className: string]: string } 17 | export default classes 18 | } 19 | 20 | interface GlobalState { 21 | settings?: any; 22 | userInfo?: { 23 | name?: string; 24 | avatar?: string; 25 | }; 26 | userLoading?: boolean; 27 | // 面包屑 28 | breadcrumb?: [], 29 | routes?: any[]; 30 | // 初始化完成 31 | inited?: boolean; 32 | openSetting?: boolean; 33 | antdToken?: any; 34 | } 35 | -------------------------------------------------------------------------------- /src/Traits/ErrorTrait.php: -------------------------------------------------------------------------------- 1 | error = $error ?: admin_trans('admin.unknown_error'); 27 | return false; 28 | } 29 | 30 | /** 31 | * 获取错误信息 32 | * 33 | * @return string 34 | */ 35 | public function getError(): string 36 | { 37 | return $this->error; 38 | } 39 | 40 | /** 41 | * 是否存在错误信息 42 | * 43 | * @return bool 44 | */ 45 | public function hasError(): bool 46 | { 47 | return !empty($this->error); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## 如何为 Owl Admin 做贡献 2 | 3 | #### 发现 Bug 了吗? 4 | 5 | - 如果该 Bug 是 OwlAdmin 的安全漏洞,请不要在 GitHub 上打开 issue,直接私信作者, 防止被漏洞被他人利用。 6 | - 在 GitHub 的 [Issues](https://github.com/Slowlyo/owl-admin/issues) 中搜索,确保该 Bug 尚未被报告。 7 | - 如果找不到针对该问题的 open issue,则可以 [打开一个新的 issue](https://github.com/Slowlyo/owl-admin/issues/new/choose)。请务必按照已有的 issue 模板进行填写。 8 | 9 | #### 要贡献代码吗? 10 | 11 | - Bug 修复 12 | - 确保 PR 清晰地描述了问题和解决方案。如果适用,请包含相关 issue 编号。 13 | - 功能性改进或新功能 14 | - 确保 PR 清晰地描述了调整/增加功能的原因。 15 | - 一次 PR 尽量提交一个功能,而不是多个功能。 16 | 17 | #### 代码格式约定 18 | 19 | - 命名 20 | - 变量名: 使用驼峰命名法,首字母小写,例如:`myVariable` 21 | - 类名:必须与文件名一致, 使用驼峰命名法,首字母大写,例如:`MyClass` 22 | - 常量:全部大写,用下划线分隔,例如:`MY_CONSTANT` 23 | - 使用有意义且可读的变量名,尽量不使用简写 24 | - 在适当的位置添加注释,以帮助理解代码 25 | - 在 `if`、`foreach`、`for`、`return` 等语句前后适当添加空行 26 | - 代码层级不超过 3 层, 尽早返回 27 | - 应尽量避免代码中出现硬编码 28 | - 避免在循环中的 io 操作 29 | - 不要保留无用代码/注释 30 | 31 | 32 | 感谢! :heart: :heart: :heart: 33 | 34 | 35 | Slowlyo 36 | -------------------------------------------------------------------------------- /admin-views/dist/assets/BarCode-BlW6OpNb.js: -------------------------------------------------------------------------------- 1 | const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/BarCode-QQbRJ0jq.js","assets/index-CEmnTf-r.js","assets/index-DrO7jWyx.css"])))=>i.map(i=>d[i]); 2 | import{l as n,_ as u,t as o,aq as p,j as t,r as h,D as v,E as _}from"./index-CEmnTf-r.js";var m=n.lazy(function(){return u(()=>import("./BarCode-QQbRJ0jq.js"),__vite__mapDeps([0,1,2]))}),f=function(a){o(e,a);function e(){return a!==null&&a.apply(this,arguments)||this}return e.prototype.render=function(){var r=this.props,s=r.className,i=r.style;r.width,r.height;var d=r.classnames,l=r.options,c=p(this.props);return t(h.Suspense,{fallback:t("div",{children:"..."}),children:t("div",{"data-testid":"barcode",className:d("BarCode",s),style:i,children:t(m,{value:c,options:l})})})},e}(n.Component),C=function(a){o(e,a);function e(){return a!==null&&a.apply(this,arguments)||this}return e=v([_({type:"barcode"})],e),e}(f);export{f as BarCodeField,C as BarCodeFieldRenderer}; 3 | -------------------------------------------------------------------------------- /src/Models/AdminRole.php: -------------------------------------------------------------------------------- 1 | belongsToMany(AdminPermission::class, 'admin_role_permissions', 'role_id', 'permission_id') 16 | ->withTimestamps(); 17 | } 18 | 19 | protected static function boot(): void 20 | { 21 | parent::boot(); 22 | static::deleting(function (AdminRole $model) { 23 | $model->permissions()->detach(); 24 | }); 25 | } 26 | 27 | public function users() 28 | { 29 | return $this->belongsToMany(AdminUser::class, 'admin_role_users', 'role_id', 'user_id')->withTimestamps(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Traits/CheckActionTrait.php: -------------------------------------------------------------------------------- 1 | _action == 'getData'; 15 | } 16 | 17 | /** 18 | * 是否为导出数据请求 19 | * 20 | * @return bool 21 | */ 22 | public function actionOfExport() 23 | { 24 | return request()->_action == 'export'; 25 | } 26 | 27 | /** 28 | * 是否为快速编辑数据请求 29 | * 30 | * @return bool 31 | */ 32 | public function actionOfQuickEdit() 33 | { 34 | return request()->_action == 'quickEdit'; 35 | } 36 | 37 | /** 38 | * 是否为快速编辑数据请求 39 | * 40 | * @return bool 41 | */ 42 | public function actionOfQuickEditItem() 43 | { 44 | return request()->_action == 'quickEditItem'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /admin-views/dist/assets/VBox-HiUdzAG-.js: -------------------------------------------------------------------------------- 1 | import{t as d,l as s,ag as o,D as m,E as f}from"./index-CEmnTf-r.js";var h=function(t){d(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.renderChild=function(n,r){var a=this.props.render;return a(n,r)},e.prototype.renderCell=function(n,r){var a=this.props.classPrefix;return s.createElement("div",{className:o("".concat(a,"Vbox-cell"),n.cellClassName)},this.renderChild("row/".concat(r),n))},e.prototype.render=function(){var n=this,r=this.props,a=r.className,p=r.style,l=r.rows,u=r.classPrefix;return s.createElement("div",{className:o("".concat(u,"Vbox"),a),style:p},Array.isArray(l)?l.map(function(c,i){return s.createElement("div",{className:o("row-row",c.rowClassName),key:i},n.renderCell(c,i))}):null)},e.propsList=["rows"],e.defaultProps={},e}(s.Component),y=function(t){d(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e=m([f({type:"vbox"})],e),e}(h);export{y as VBoxRenderer,h as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/ini-BvajGCUy.js: -------------------------------------------------------------------------------- 1 | var e={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"}]},n={defaultToken:"",tokenPostfix:".ini",escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[[/^\[[^\]]*\]/,"metatag"],[/(^\w+)(\s*)(\=)/,["key","","delimiter"]],{include:"@whitespace"},[/\d+/,"number"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/'([^'\\]|\\.)*$/,"string.invalid"],[/"/,"string",'@string."'],[/'/,"string","@string.'"]],whitespace:[[/[ \t\r\n]+/,""],[/^\s*[#;].*$/,"comment"]],string:[[/[^\\"']+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/["']/,{cases:{"$#==$S2":{token:"string",next:"@pop"},"@default":"string"}}]]}};export{e as conf,n as language}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/JSONSchema-BTUn0wAK.js: -------------------------------------------------------------------------------- 1 | import{bU as s,bV as c,t as r,v as l,l as o,z as u,D as i,Q as d,T as a,a2 as p}from"./index-CEmnTf-r.js";var h=s({sourceField:"schema",injectedPropsFilter:function(n,t){return{schema:n.config,loading:n.loading}}})(c),m=function(n){r(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t.prototype.controlRef=function(e){for(;e!=null&&e.getWrappedInstance;)e=e.getWrappedInstance();this.control=e},t.prototype.validate=function(){var e;return(e=this.control)===null||e===void 0?void 0:e.validate()},t.prototype.render=function(){var e=l(this.props,[]);return o.createElement(h,u({},e,{ref:this.controlRef}))},i([d,a("design:type",Function),a("design:paramtypes",[Object]),a("design:returntype",void 0)],t.prototype,"controlRef",null),t}(o.PureComponent),v=function(n){r(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t=i([p({type:"json-schema",strictMode:!1})],t),t}(m);export{v as JSONSchemaRenderer,m as default}; 2 | -------------------------------------------------------------------------------- /src/Renderers/SchemaCopyable.php: -------------------------------------------------------------------------------- 1 | ` 21 | 更多文档:https://aisuda.bce.baidu.com/amis/zh-CN/docs/concepts/template) 22 | */ 23 | public function content($value = '') 24 | { 25 | return $this->set('content', $value); 26 | } 27 | 28 | /** 29 | * 可以配置图标 (iconfont 里面的类名。) 30 | */ 31 | public function icon($value = '') 32 | { 33 | return $this->set('icon', $value); 34 | } 35 | 36 | /** 37 | * 提示文字内容 38 | */ 39 | public function tooltip($value = '') 40 | { 41 | return $this->set('tooltip', $value); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /admin-views/dist/assets/SparkLine-Dv5W1vFp.js: -------------------------------------------------------------------------------- 1 | import{t as m,a4 as h,aq as v,l as r,dJ as C,z as d,ae as k,D as u,Q as y,T as c,E as f}from"./index-CEmnTf-r.js";var g=function(o){m(t,o);function t(){return o!==null&&o.apply(this,arguments)||this}return t.prototype.handleClick=function(e,i){var a=this.props,p=a.disabled,n=a.onAction,s=a.clickAction,l=a.data;e.defaultPrevented||!s||p||n==null||n(null,s,i?h(l,i):l)},t.prototype.render=function(){var e=this.props;e.value,e.name;var i=e.clickAction,a=e.id,p=e.wrapperCustomStyle,n=e.env,s=e.themeCss,l=v(this.props)||[1,1];return r.createElement(r.Fragment,null,r.createElement(C,d({onClick:i?this.handleClick:void 0},this.props,{value:l})),r.createElement(k,d({},this.props,{config:{wrapperCustomStyle:p,id:a,themeCss:s,classNames:[{key:"baseControlClassName"}]},env:n})))},u([y,c("design:type",Function),c("design:paramtypes",[Object,Object]),c("design:returntype",void 0)],t.prototype,"handleClick",null),t=u([f({type:"sparkline"})],t),t}(r.Component);export{g as SparkLineRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Password-y2UY9u3i.js: -------------------------------------------------------------------------------- 1 | import{t as o,l as i,M as l,D as r,Q as v,T as a,E as g}from"./index-CEmnTf-r.js";var b=function(s){o(e,s);function e(){var t=s!==null&&s.apply(this,arguments)||this;return t.state={visible:!1},t}return e.prototype.toggleVisible=function(){this.setState({visible:!this.state.visible})},e.prototype.render=function(){var t=this.props,c=t.classnames,d=t.className,m=t.style,n=t.mosaicText,p=n===void 0?"********":n,u=t.value;return i.createElement("span",{className:c("Password-field",d),style:m},this.state.visible?u:p,this.state.visible?i.createElement(l,{icon:"view",className:"icon",onClick:this.toggleVisible}):i.createElement(l,{icon:"invisible",className:"icon",onClick:this.toggleVisible}))},r([v,a("design:type",Function),a("design:paramtypes",[]),a("design:returntype",void 0)],e.prototype,"toggleVisible",null),e}(i.Component),y=function(s){o(e,s);function e(){return s!==null&&s.apply(this,arguments)||this}return e=r([g({type:"password"})],e),e}(b);export{b as PasswordField,y as PasswordFieldRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/DateRange-CReX7c1E.js: -------------------------------------------------------------------------------- 1 | import{t as _,aK as h,ak as o,l as D,D as M,E as x}from"./index-CEmnTf-r.js";var N=function(r){_(t,r);function t(){return r!==null&&r.apply(this,arguments)||this}return t.prototype.render=function(){var n=this.props,s=n.delimiter,g=s===void 0?",":s,d=n.connector,y=d===void 0?"~":d,i=n.value,l=n.valueFormat,m=n.format,c=m===void 0?"YYYY-MM-DD":m,u=n.displayFormat,F=n.classnames,R=n.className,Y=n.style;if(!i)return null;typeof i=="string"&&(i=i.split(g));var f=h(i,2),v=f[0],e=v===void 0?"":v,p=f[1],a=p===void 0?"":p;return l?(e=o(e,l),a=o(a,l)):(e=o(e*1e3),a=o(a*1e3)),e=e!=null&&e.isValid()?e.format(u||c):"",a=a!=null&&a.isValid()?a.format(u||c):"",D.createElement("span",{className:F("DateRangeField",R),style:Y},[e,a].join(" ".concat(y," ")))},t.defaultProps={format:"YYYY-MM-DD",valueFormat:"X",connector:"~"},t}(D.Component),T=function(r){_(t,r);function t(){return r!==null&&r.apply(this,arguments)||this}return t=M([x({type:"date-range"})],t),t}(N);export{N as DateRangeField,T as DateRangeFieldRenderer}; 2 | -------------------------------------------------------------------------------- /src/Renderers/WebComponent.php: -------------------------------------------------------------------------------- 1 | set('type', 'web-component'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 子节点 22 | */ 23 | public function body($value = '') 24 | { 25 | return $this->set('body', $value); 26 | } 27 | 28 | /** 29 | * 标签上的属性 30 | */ 31 | public function props($value = '') 32 | { 33 | return $this->set('props', $value); 34 | } 35 | 36 | /** 37 | * 具体使用的 web-component 标签 38 | */ 39 | public function tag($value = '') 40 | { 41 | return $this->set('tag', $value); 42 | } 43 | 44 | /** 45 | * 指定为 web-component 渲染器。 46 | */ 47 | public function type($value = 'web-component') 48 | { 49 | return $this->set('type', $value); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/Renderers/SchemaMessage.php: -------------------------------------------------------------------------------- 1 | set('fetchFailed', $value); 25 | } 26 | 27 | /** 28 | * 获取成功的提示,默认为空。 29 | */ 30 | public function fetchSuccess($value = '') 31 | { 32 | return $this->set('fetchSuccess', $value); 33 | } 34 | 35 | /** 36 | * 保存失败时的提示。 37 | */ 38 | public function saveFailed($value = '') 39 | { 40 | return $this->set('saveFailed', $value); 41 | } 42 | 43 | /** 44 | * 保存成功时的提示。 45 | */ 46 | public function saveSuccess($value = '') 47 | { 48 | return $this->set('saveSuccess', $value); 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/Renderers/ChartRadios.php: -------------------------------------------------------------------------------- 1 | set('type', 'chart-radios'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 图表数值字段名 22 | */ 23 | public function chartValueField($value = '') 24 | { 25 | return $this->set('chartValueField', $value); 26 | } 27 | 28 | /** 29 | * 图表配置 30 | */ 31 | public function config($value = '') 32 | { 33 | return $this->set('config', $value); 34 | } 35 | 36 | /** 37 | * 高亮的时候是否显示 tooltip 38 | */ 39 | public function showTooltipOnHighlight($value = true) 40 | { 41 | return $this->set('showTooltipOnHighlight', $value); 42 | } 43 | 44 | /** 45 | * 指定为 chart-radios 渲染器。 46 | */ 47 | public function type($value = 'chart-radios') 48 | { 49 | return $this->set('type', $value); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/Renderers/ComboCondition.php: -------------------------------------------------------------------------------- 1 | set('items', $value); 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | public function label($value = '') 31 | { 32 | return $this->set('label', $value); 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | public function mode($value = '') 39 | { 40 | return $this->set('mode', $value); 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | public function scaffold($value = '') 47 | { 48 | return $this->set('scaffold', $value); 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | public function test($value = '') 55 | { 56 | return $this->set('test', $value); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/Support/Apis/DataListApi.php: -------------------------------------------------------------------------------- 1 | success($this->service()->list()); 22 | } 23 | 24 | public function argsSchema() 25 | { 26 | return [ 27 | amis()->SelectControl('model', admin_trans('admin.relationships.model')) 28 | ->required() 29 | ->menuTpl('${label} ${table}') 30 | ->source('/dev_tools/relation/model_options') 31 | ->searchable(), 32 | ]; 33 | } 34 | 35 | protected function service() 36 | { 37 | $service = $this->blankService(); 38 | 39 | $service->setModelName($this->getArgs('model')); 40 | 41 | return $service; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Slowlyo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Renderers/ConditionGroupValue.php: -------------------------------------------------------------------------------- 1 | set('conjunction', 'and'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 22 | */ 23 | public function children($value = '') 24 | { 25 | return $this->set('children', $value); 26 | } 27 | 28 | /** 29 | * 可选值: and | or 30 | */ 31 | public function conjunction($value = '') 32 | { 33 | return $this->set('conjunction', $value); 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | public function id($value = '') 40 | { 41 | return $this->set('id', $value); 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | public function if($value = '') 48 | { 49 | return $this->set('if', $value); 50 | } 51 | 52 | /** 53 | * 54 | */ 55 | public function not($value = true) 56 | { 57 | return $this->set('not', $value); 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/Models/Extension.php: -------------------------------------------------------------------------------- 1 | 'json', 13 | ]; 14 | 15 | protected $table = 'admin_extensions'; 16 | 17 | protected static function booted() 18 | { 19 | $clearCache = function () { 20 | cache()->forget(self::CACHE_KEY); 21 | }; 22 | 23 | static::created($clearCache); 24 | static::updated($clearCache); 25 | static::deleted($clearCache); 26 | } 27 | 28 | public static function keyByNameList() 29 | { 30 | return cache()->rememberForever(self::CACHE_KEY, fn() => self::all()->keyBy('name')); 31 | } 32 | 33 | public static function getEnabledNames() 34 | { 35 | $list = self::keyByNameList(); 36 | 37 | $enabled = []; 38 | foreach ($list as $item) { 39 | if ($item->is_enabled) { 40 | $enabled[] = $item->name; 41 | } 42 | } 43 | return $enabled; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Link-B5v7OQvd.js: -------------------------------------------------------------------------------- 1 | import{t as c,L as _,aq as C,l as p,dy as L,D as h,Q as T,T as o,E as R,a0 as F}from"./index-CEmnTf-r.js";var I=function(a){c(t,a);function t(){return a!==null&&a.apply(this,arguments)||this}return t.prototype.handleClick=function(e){var n=this.props,r=n.env,i=n.href,l=n.blank,s=n.body;r==null||r.tracker({eventType:"url",eventData:{url:i,blank:l,label:s}},this.props)},t.prototype.getHref=function(){},t.prototype.render=function(){var e=this.props,n=e.className,r=e.style,i=e.body,l=e.href;e.classnames;var s=e.blank,u=e.disabled,f=e.htmlTarget,y=e.data,b=e.render,k=e.translate,m=e.title,g=e.icon,v=e.rightIcon,d=(typeof l=="string"&&l?_(l,y,"| raw"):void 0)||C(this.props);return p.createElement(L,{className:n,style:r,href:d,disabled:u,title:m,htmlTarget:f||(s?"_blank":"_self"),icon:g,rightIcon:v,onClick:this.handleClick},i?b("body",i):d||k("link"))},t.defaultProps={blank:!0,disabled:!1,htmlTarget:""},h([T,o("design:type",Function),o("design:paramtypes",[Object]),o("design:returntype",void 0)],t.prototype,"handleClick",null),t}(p.Component),w=function(a){c(t,a);function t(){return a!==null&&a.apply(this,arguments)||this}return t=h([R({type:"link"}),F],t),t}(I);export{I as LinkCmpt,w as LinkFieldRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/src/utils/clipboard.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/feross/clipboard-copy/blob/master/index.js 2 | 3 | export default function clipboard(text) { 4 | if (navigator.clipboard) { 5 | return navigator.clipboard.writeText(text).catch(function (err) { 6 | throw err !== undefined 7 | ? err 8 | : new DOMException('The request is not allowed', 'NotAllowedError'); 9 | }); 10 | } 11 | 12 | const span = document.createElement('span'); 13 | span.textContent = text; 14 | 15 | span.style.whiteSpace = 'pre'; 16 | 17 | document.body.appendChild(span); 18 | 19 | const selection = window.getSelection(); 20 | const range = window.document.createRange(); 21 | selection.removeAllRanges(); 22 | range.selectNode(span); 23 | selection.addRange(range); 24 | 25 | let success = false; 26 | try { 27 | success = window.document.execCommand('copy'); 28 | } catch (err) { 29 | // eslint-disable-next-line 30 | console.log('error', err); 31 | } 32 | 33 | selection.removeAllRanges(); 34 | window.document.body.removeChild(span); 35 | 36 | return success 37 | ? Promise.resolve() 38 | : Promise.reject( 39 | new DOMException('The request is not allowed', 'NotAllowedError') 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /admin-views/dist/assets/GridNav-Ck4ekt-U.js: -------------------------------------------------------------------------------- 1 | import{t as h,e2 as g,e3 as b,aq as _,w as m,x as A,l as c,e4 as C,z as N,e5 as x,D as v,Q as E,T as d,E as T}from"./index-CEmnTf-r.js";var w=function(i){h(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return t.prototype.handleClick=function(e){var n=this;return function(l){var r;e.link?r=g.isUrl({},e.link)?{type:"button",actionType:"url",url:e.link,blank:e.blank}:{type:"button",actionType:"link",link:e.link}:r=e.clickAction,b(l,r,n.props,e)}},t.prototype.render=function(){var e=this,n=this.props,l=n.itemClassName;n.style;var r=n.contentClassName,o=n.source,u=n.data,p=n.options,y=n.classnames,f=_(this.props),a=[];return typeof o=="string"&&m(o)?a=A(o,u,"| raw")||void 0:Array.isArray(f)?a=f:Array.isArray(p)&&(a=p),a&&!Array.isArray(a)&&(a=[a]),a!=null&&a.length?c.createElement(C,N({},this.props),a.map(function(s,k){return c.createElement(x,{key:k,onClick:s.clickAction||s.link?e.handleClick(s):void 0,className:l,contentClassName:r,text:s.text,icon:s.icon,classnames:y,badge:s.badge?{badge:s.badge,data:u,classnames:y}:void 0})})):null},v([E,d("design:type",Function),d("design:paramtypes",[Object]),d("design:returntype",void 0)],t.prototype,"handleClick",null),t=v([T({type:"grid-nav"})],t),t}(c.Component);export{w as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/PaginationWrapper-D-69aPye.js: -------------------------------------------------------------------------------- 1 | import{t as l,l as o,D as m,E as P,dh as c}from"./index-CEmnTf-r.js";var y=function(r){l(a,r);function a(e){var t=r.call(this,e)||this;return e.store.syncProps(e,void 0,["perPage","mode","ellipsisPageGap","inputName","outputName"]),t}return a.prototype.componentDidUpdate=function(e){var t=this.props.store;t.syncProps(this.props,e,["perPage","mode","ellipsisPageGap","inputName","outputName"])},a.prototype.render=function(){var e=this.props,t=e.position,p=e.render,n=e.store,g=e.classnames,u=e.style,i=e.body,d=e.translate,s=t!=="none"?p("pager",{type:"pagination"},{activePage:n.page,lastPage:n.lastPage,mode:n.mode,ellipsisPageGap:n.ellipsisPageGap,onPageChange:n.switchTo,perPage:n.perPage,className:"PaginationWrapper-pager"}):null;return o.createElement("div",{className:g("PaginationWrapper"),style:u},t==="top"?s:null,i?p("body",i,{data:n.locals}):o.createElement("span",null,d("PaginationWrapper.placeholder")),t==="bottom"?s:null)},a.defaultProps={inputName:"items",outputName:"items",perPage:10,position:"top"},a}(o.Component),f=function(r){l(a,r);function a(){return r!==null&&r.apply(this,arguments)||this}return a=m([P({type:"pagination-wrapper",storeType:c.name})],a),a}(y);export{y as PaginationWrapper,f as PaginationWrapperRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/src/utils/dynamicAssets.ts: -------------------------------------------------------------------------------- 1 | export function dynamicAssetsHandler({js = [], css = [], styles = [], scripts = []}) { 2 | const appendToHead = (element: any) => document.getElementsByTagName('head')[0].appendChild(element) 3 | 4 | const loadJS = (src: string) => { 5 | const script = document.createElement('script') 6 | script.src = src 7 | script.type = 'text/javascript' 8 | appendToHead(script) 9 | } 10 | 11 | const loadCSS = (href: string) => { 12 | const link = document.createElement('link') 13 | link.href = href 14 | link.rel = 'stylesheet' 15 | appendToHead(link) 16 | } 17 | 18 | const loadScripts = (js: string) => { 19 | const script = document.createElement('script') 20 | script.innerHTML = js 21 | script.type = 'text/javascript' 22 | appendToHead(script) 23 | } 24 | 25 | const loadStyles = (css: string) => { 26 | const style = document.createElement('style') 27 | style.innerHTML = css 28 | appendToHead(style) 29 | } 30 | 31 | js?.forEach(js => loadJS(js)) 32 | css?.forEach(css => loadCSS(css)) 33 | scripts?.forEach(val => loadScripts(val)) 34 | styles?.forEach(val => loadStyles(val)) 35 | } 36 | -------------------------------------------------------------------------------- /src/Renderers/QRCodeImageSettings.php: -------------------------------------------------------------------------------- 1 | set('excavate', $value); 25 | } 26 | 27 | /** 28 | * 29 | */ 30 | public function height($value = '') 31 | { 32 | return $this->set('height', $value); 33 | } 34 | 35 | /** 36 | * 37 | */ 38 | public function src($value = '') 39 | { 40 | return $this->set('src', $value); 41 | } 42 | 43 | /** 44 | * 45 | */ 46 | public function width($value = '') 47 | { 48 | return $this->set('width', $value); 49 | } 50 | 51 | /** 52 | * 53 | */ 54 | public function x($value = '') 55 | { 56 | return $this->set('x', $value); 57 | } 58 | 59 | /** 60 | * 61 | */ 62 | public function y($value = '') 63 | { 64 | return $this->set('y', $value); 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /admin-views/dist/assets/csp-C46ZqvIl.js: -------------------------------------------------------------------------------- 1 | var t={brackets:[],autoClosingPairs:[],surroundingPairs:[]},r={keywords:[],typeKeywords:[],tokenPostfix:".csp",operators:[],symbols:/[=> div { 41 | margin-bottom: 0 !important; 42 | overflow-x: hidden !important; 43 | } 44 | 45 | .ant-menu-item-icon { 46 | vertical-align: -0.225rem !important; 47 | } 48 | 49 | .iframe:has(.owl-iframe) { 50 | padding: 0; 51 | } 52 | 53 | .custom-scrollbar > :first-child { 54 | scrollbar-width: none; 55 | margin-right: 0 !important; 56 | margin-bottom: 0 !important; 57 | } 58 | -------------------------------------------------------------------------------- /src/Renderers/AutoGenerateFilter.php: -------------------------------------------------------------------------------- 1 | set('columnsNum', $value); 25 | } 26 | 27 | /** 28 | * 是否默认收起 29 | */ 30 | public function defaultCollapsed($value = true) 31 | { 32 | return $this->set('defaultCollapsed', $value); 33 | } 34 | 35 | /** 36 | * 是否启用多选框 37 | */ 38 | public function enableBulkActions($value = true) 39 | { 40 | return $this->set('enableBulkActions', $value); 41 | } 42 | 43 | /** 44 | * 启用批量操作的表达式 (表达式,语法 `data.xxx > 5`。) 45 | */ 46 | public function enableBulkActionsOn($value = '') 47 | { 48 | return $this->set('enableBulkActionsOn', $value); 49 | } 50 | 51 | /** 52 | * 是否显示设置查询字段 53 | */ 54 | public function showBtnToolbar($value = true) 55 | { 56 | return $this->set('showBtnToolbar', $value); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/Support/CodeGenerator/RouteGenerator.php: -------------------------------------------------------------------------------- 1 | getModel()->query()->where('url', $_url)->exists()) { 21 | $adminMenuService->store([ 22 | 'title' => $menuInfo['title'], 23 | 'icon' => $menuInfo['icon'], 24 | 'parent_id' => $menuInfo['parent_id'], 25 | 'url' => $_url, 26 | 'custom_order' => 100, 27 | ]); 28 | } 29 | 30 | if ($adminMenuService->hasError()) { 31 | abort(500, $adminMenuService->getError()); 32 | } 33 | 34 | // 刷新路由 35 | Artisan::call('admin:gen-route'); 36 | } 37 | 38 | public static function refresh() 39 | { 40 | Artisan::call('admin:gen-route'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /admin-views/src/utils/useStorage.ts: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/questions/68424114/next-js-how-to-fetch-localstorage-data-before-client-side-rendering 2 | // 解决 nextJS 无法获取初始localstorage问题 3 | 4 | import { useEffect, useState } from 'react'; 5 | import {isSSR} from '@/utils/common' 6 | 7 | const getDefaultStorage = (key) => { 8 | if (!isSSR) { 9 | return localStorage.getItem(key); 10 | } else { 11 | return undefined; 12 | } 13 | }; 14 | 15 | function useStorage( 16 | key: string, 17 | defaultValue?: string 18 | ): [string, (string) => void, () => void] { 19 | const [storedValue, setStoredValue] = useState( 20 | getDefaultStorage(key) || defaultValue 21 | ); 22 | 23 | const setStorageValue = (value: string) => { 24 | if (!isSSR) { 25 | localStorage.setItem(key, value); 26 | if (value !== storedValue) { 27 | setStoredValue(value); 28 | } 29 | } 30 | }; 31 | 32 | const removeStorage = () => { 33 | if (!isSSR) { 34 | localStorage.removeItem(key); 35 | } 36 | }; 37 | 38 | useEffect(() => { 39 | const storageValue = localStorage.getItem(key); 40 | if (storageValue) { 41 | setStoredValue(storageValue); 42 | } 43 | }, []); 44 | 45 | return [storedValue, setStorageValue, removeStorage]; 46 | } 47 | 48 | export default useStorage; 49 | -------------------------------------------------------------------------------- /src/Support/Apis/DataDetailApi.php: -------------------------------------------------------------------------------- 1 | service()->getDetail(request($this->getArgs('primary_key', 'id'))); 22 | 23 | return Admin::response()->success($data); 24 | } 25 | 26 | public function argsSchema() 27 | { 28 | return [ 29 | amis()->SelectControl('model', admin_trans('admin.relationships.model')) 30 | ->required() 31 | ->menuTpl('${label} ${table}') 32 | ->source('/dev_tools/relation/model_options') 33 | ->searchable(), 34 | amis()->TextControl('primary_id', admin_trans('admin.code_generators.primary_key'))->value('id'), 35 | ]; 36 | } 37 | 38 | protected function service() 39 | { 40 | $service = $this->blankService(); 41 | 42 | $service->setModelName($this->getArgs('model')); 43 | 44 | return $service; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Renderers/Markdown.php: -------------------------------------------------------------------------------- 1 | set('type', 'markdown'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 类名 22 | */ 23 | public function className($value = '') 24 | { 25 | return $this->set('className', $value); 26 | } 27 | 28 | /** 29 | * 名称 30 | */ 31 | public function name($value = '') 32 | { 33 | return $this->set('name', $value); 34 | } 35 | 36 | /** 37 | * 设置 Markdown 的配置 38 | */ 39 | public function options($value = '') 40 | { 41 | return $this->set('options', $value); 42 | } 43 | 44 | /** 45 | * 外部地址 46 | */ 47 | public function src($value = '') 48 | { 49 | return $this->set('src', $value); 50 | } 51 | 52 | /** 53 | * 指定为 markdown 渲染器。 54 | */ 55 | public function type($value = 'markdown') 56 | { 57 | return $this->set('type', $value); 58 | } 59 | 60 | /** 61 | * 静态值 62 | */ 63 | public function value($value = '') 64 | { 65 | return $this->set('value', $value); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /admin-views/vite.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig, loadEnv} from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import compression from 'vite-plugin-compression' 4 | import {createViteProxy} from './src/utils/proxy' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig(configEnv => { 8 | const viteEnv = loadEnv(configEnv.mode, process.cwd()) 9 | 10 | return { 11 | base: viteEnv.VITE_BASE_URL, 12 | resolve: { 13 | alias: [ 14 | {find: '@', replacement: '/src'}, 15 | {find: 'moment/locale/zh-cn', replacement: 'moment/dist/locale/zh-cn'}, 16 | ], 17 | }, 18 | plugins: [ 19 | react(), 20 | compression(), 21 | ], 22 | css: { 23 | preprocessorOptions: { 24 | less: { 25 | javascriptEnabled: true, 26 | }, 27 | }, 28 | }, 29 | server: { 30 | host: '0.0.0.0', 31 | port: 3200, 32 | open: true, 33 | proxy: createViteProxy(viteEnv), 34 | }, 35 | build: { 36 | sourcemap: false, 37 | reportCompressedSize: false, 38 | rollupOptions: { 39 | onwarn() { 40 | }, 41 | }, 42 | }, 43 | } 44 | }) 45 | -------------------------------------------------------------------------------- /admin-views/dist/assets/InputColor-B1H9OsY3.js: -------------------------------------------------------------------------------- 1 | const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ColorPicker-Ba-arFiF.js","assets/index-CEmnTf-r.js","assets/index-DrO7jWyx.css"])))=>i.map(i=>d[i]); 2 | import{l as c,_ as m,t as u,v as _,j as o,ag as f,r as C,z as y,D as p,ap as h,T as n,a2 as g}from"./index-CEmnTf-r.js";var x=c.lazy(function(){return m(()=>import("./ColorPicker-Ba-arFiF.js"),__vite__mapDeps([0,1,2]))}),P=function(r){u(t,r);function t(){var e=r!==null&&r.apply(this,arguments)||this;return e.state={open:!1},e}return t.prototype.render=function(){var e=this.props,d=e.className;e.style;var l=e.classPrefix,v=e.value,a=e.env;e.static;var s=e.mobileUI,i=_(e,["className","style","classPrefix","value","env","static","mobileUI"]);return o("div",{className:f("".concat(l,"ColorControl"),d),children:o(C.Suspense,{fallback:o("div",{children:"..."}),children:o(x,{...y({classPrefix:l},i,{mobileUI:s,popOverContainer:s?a==null?void 0:a.getModalContainer:i.popOverContainer||a.getModalContainer,value:v||""})})})})},t.defaultProps={format:"hex",clearable:!0},p([h(),n("design:type",Function),n("design:paramtypes",[]),n("design:returntype",void 0)],t.prototype,"render",null),t}(c.PureComponent),I=function(r){u(t,r);function t(){return r!==null&&r.apply(this,arguments)||this}return t=p([g({type:"input-color"})],t),t}(P);export{I as ColorControlRenderer,x as ColorPicker,P as default}; 3 | -------------------------------------------------------------------------------- /src/Models/AdminMenu.php: -------------------------------------------------------------------------------- 1 | admin_trans('admin.admin_menu.route'), 21 | self::TYPE_LINK => admin_trans('admin.admin_menu.link'), 22 | self::TYPE_IFRAME => admin_trans('admin.admin_menu.iframe'), 23 | self::TYPE_PAGE => admin_trans('admin.admin_menu.page'), 24 | ]; 25 | } 26 | 27 | /** 28 | * 父级菜单 29 | * 30 | * @return BelongsTo 31 | */ 32 | public function parent(): BelongsTo 33 | { 34 | return $this->belongsTo(self::class, 'parent_id'); 35 | } 36 | 37 | public function title(): Attribute 38 | { 39 | return Attribute::get(function ($value) { 40 | $transKey = ($this->extension ? $this->extension . '::' : '') . "menu.{$value}"; 41 | $translate = admin_trans($transKey); 42 | 43 | return $translate == $transKey ? $value : $translate; 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /admin-views/src/pages/login/DefaultLogin/bg/style/index.module.css: -------------------------------------------------------------------------------- 1 | .bg { 2 | width: 100%; 3 | height: 100vh; 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | position: relative; 8 | } 9 | 10 | .waves { 11 | position: absolute; 12 | width: 100%; 13 | height: 15vh; 14 | min-height: 100px; 15 | max-height: 150px; 16 | bottom: 20vh; 17 | } 18 | 19 | .bottom-block { 20 | position: absolute; 21 | width: 100%; 22 | height: 20vh; 23 | bottom: 0; 24 | } 25 | 26 | .parallax > use { 27 | animation: move-forever 25s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite; 28 | } 29 | 30 | .parallax > use:nth-child(1) { 31 | animation-delay: -2s; 32 | animation-duration: 7s; 33 | } 34 | 35 | .parallax > use:nth-child(2) { 36 | animation-delay: -3s; 37 | animation-duration: 10s; 38 | } 39 | 40 | .parallax > use:nth-child(3) { 41 | animation-delay: -4s; 42 | animation-duration: 13s; 43 | } 44 | 45 | .parallax > use:nth-child(4) { 46 | animation-delay: -5s; 47 | animation-duration: 20s; 48 | } 49 | 50 | @keyframes move-forever { 51 | 0% { 52 | transform: translate3d(-90px, 0, 0); 53 | } 54 | 100% { 55 | transform: translate3d(85px, 0, 0); 56 | } 57 | } 58 | 59 | @media (max-width: 768px) { 60 | .waves { 61 | height: 40px; 62 | min-height: 40px; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Renderers/Expandable.php: -------------------------------------------------------------------------------- 1 | set('expandableOn', $value); 25 | } 26 | 27 | /** 28 | * 展开行自定义样式表达式 29 | */ 30 | public function expandedRowClassNameExpr($value = '') 31 | { 32 | return $this->set('expandedRowClassNameExpr', $value); 33 | } 34 | 35 | /** 36 | * 已展开的key值 37 | */ 38 | public function expandedRowKeys($value = '') 39 | { 40 | return $this->set('expandedRowKeys', $value); 41 | } 42 | 43 | /** 44 | * 已展开的key值表达式 45 | */ 46 | public function expandedRowKeysExpr($value = '') 47 | { 48 | return $this->set('expandedRowKeysExpr', $value); 49 | } 50 | 51 | /** 52 | * 对应数据源的key值 53 | */ 54 | public function keyField($value = '') 55 | { 56 | return $this->set('keyField', $value); 57 | } 58 | 59 | /** 60 | * 对应渲染器类型 61 | */ 62 | public function type($value = '') 63 | { 64 | return $this->set('type', $value); 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Number-BUnbYTq2.js: -------------------------------------------------------------------------------- 1 | import{t as d,l as a,aq as k,bB as R,ck as O,bD as S,dU as w,bF as D,D as M,E as P}from"./index-CEmnTf-r.js";var V=function(n){d(r,n);function r(){return n!==null&&n.apply(this,arguments)||this}return r.prototype.render=function(){var t=this.props,b=t.placeholder,v=t.kilobitSeparator,s=t.precision,N=t.prefix,o=t.affix,h=t.suffix,u=t.percent,p=t.unitOptions,x=t.className,y=t.style,F=t.classnames,g=t.translate,i=a.createElement("span",{className:"text-muted"},b),e=k(this.props),l="";if(typeof e=="string"&&p&&p.length){var E=R(p).map(function(f){return f.value});l=E.find(function(f){return e.endsWith(f)})||"",l&&(e=e.replace(l,""))}if(typeof e=="number"||typeof e=="string")if(typeof e=="string"&&s&&(e=O(parseFloat(e))),isNaN(e))i=!1;else if(u){e=parseFloat(e)||0;var m=typeof u=="number"?u:0,_=e*100,c=Math.pow(10,m);e=(Math.round(_*c)/c).toFixed(m)+"%",i=a.createElement("span",null,e)}else typeof e=="number"&&s&&(e=S(w(e),".",s)),v&&(e=D(e,s)),i=a.createElement("span",null,e);return i=i?a.createElement(a.Fragment,null,N,i,l,o??h):a.createElement("span",{className:"text-danger"},g("Number.invalid")),a.createElement("span",{className:F("NumberField",x),style:y},i)},r.defaultProps={placeholder:"-",kilobitSeparator:!0},r}(a.Component),z=function(n){d(r,n);function r(){return n!==null&&n.apply(this,arguments)||this}return r=M([P({type:"number"})],r),r}(V);export{V as NumberField,z as NumberFieldRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/JSONSchemaEditor-B2Y_oqnh.js: -------------------------------------------------------------------------------- 1 | import{t as c,aw as v,z as i,bW as l,aJ as f,v as S,l as p,bX as b,D as u,Q as g,T as s,a2 as y}from"./index-CEmnTf-r.js";var O=function(n){c(e,n);function e(){return n!==null&&n.apply(this,arguments)||this}return e.prototype.normalizePlaceholder=function(){var t=this.props.placeholder;return v(t)?i(i({},l),f(t,["key","title","description","default","empty"])):l},e.prototype.renderModalProps=function(t,d){var o=this.props,r=o.render,a=o.advancedSettings,m=(a==null?void 0:a[t==null?void 0:t.type])||[];return r("modal",{type:"form",wrapWithPanel:!1,body:m,submitOnChange:!0},{data:t,onSubmit:function(h){return d(h)}})},e.prototype.render=function(){var t=this.props,d=t.enableAdvancedSetting,o=t.mobileUI,r=t.env,a=S(t,["enableAdvancedSetting","mobileUI","env"]);return p.createElement(b,i({},a,{mobileUI:o,placeholder:this.normalizePlaceholder(),enableAdvancedSetting:d,renderModalProps:this.renderModalProps,popOverContainer:o?r==null?void 0:r.getModalContainer:a.popOverContainer||r.getModalContainer}))},e.defaultProps={enableAdvancedSetting:!1,placeholder:l},u([g,s("design:type",Function),s("design:paramtypes",[Object,Function]),s("design:returntype",void 0)],e.prototype,"renderModalProps",null),e}(p.PureComponent),_=function(n){c(e,n);function e(){return n!==null&&n.apply(this,arguments)||this}return e=u([y({type:"json-schema-editor"})],e),e}(O);export{_ as JSONSchemaEditorRenderer,O as default}; 2 | -------------------------------------------------------------------------------- /admin-views/src/routes/helpers.ts: -------------------------------------------------------------------------------- 1 | import lazyload from "@/utils/lazyload" 2 | import {isArray, isString} from '@/utils/common' 3 | 4 | // 路由懒加载 5 | export const componentMount = (routes) => { 6 | const mod = import.meta.glob("../pages/**/[a-z[]*.tsx") 7 | 8 | const travel = (_routes, parents = []) => { 9 | return _routes.map((route) => { 10 | if (route.path && !route.children) { 11 | if (isString(route.component)) { 12 | route.component = lazyload(mod[`../pages/${route.component}/index.tsx`]) 13 | } 14 | } else if (isArray(route.children) && route.children.length) { 15 | route.children = travel(route.children, [...parents, route]) 16 | } 17 | 18 | // 保存父级路由 19 | route.meta.parents = parents 20 | 21 | return route 22 | }) 23 | } 24 | 25 | return travel(routes) 26 | } 27 | 28 | // 获取所有路由 29 | export const getFlattenRoutes = (routes) => { 30 | const flattenRoutes = [] 31 | 32 | const stack = [...routes] 33 | while (stack.length) { 34 | const route = stack.pop() 35 | if (route.path && !route.children) { 36 | flattenRoutes.push(route) 37 | } else if (isArray(route.children) && route.children.length) { 38 | stack.push(...route.children) 39 | } 40 | } 41 | 42 | return flattenRoutes 43 | } 44 | -------------------------------------------------------------------------------- /src/Models/PersonalAccessToken.php: -------------------------------------------------------------------------------- 1 | setConnection(Admin::config('admin.database.connection')); 13 | 14 | parent::__construct($attributes); 15 | } 16 | 17 | public static function findToken($token) 18 | { 19 | if (!str_contains($token, '|')) { 20 | return static::where('token', hash('sha256', $token))->withInExpiration()->first(); 21 | } 22 | 23 | [$id, $token] = explode('|', $token, 2); 24 | 25 | $instance = static::withInExpiration()->find($id); 26 | 27 | if ($instance) { 28 | return hash_equals($instance->token, hash('sha256', $token)) ? $instance : null; 29 | } 30 | 31 | return null; 32 | } 33 | 34 | public function scopeWithInExpiration($query) 35 | { 36 | $expiration = config('admin.auth.token_expiration'); 37 | 38 | $query->when($expiration, function ($q) use ($expiration) { 39 | $q->where('last_used_at', '>=', now()->subMinutes($expiration)); 40 | $q->orWhereNull('last_used_at'); 41 | }); 42 | 43 | return $query; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Renderers/ImageToolbarAction.php: -------------------------------------------------------------------------------- 1 | set('key', 'ROTATE_RIGHT'); 16 | 17 | 18 | } 19 | 20 | /** 21 | * 确认弹窗标题 22 | */ 23 | public function confirmTitle($value = '') 24 | { 25 | return $this->set('confirmTitle', $value); 26 | } 27 | 28 | /** 29 | * 30 | */ 31 | public function disabled($value = true) 32 | { 33 | return $this->set('disabled', $value); 34 | } 35 | 36 | /** 37 | * 38 | */ 39 | public function icon($value = '') 40 | { 41 | return $this->set('icon', $value); 42 | } 43 | 44 | /** 45 | * 46 | */ 47 | public function iconClassName($value = '') 48 | { 49 | return $this->set('iconClassName', $value); 50 | } 51 | 52 | /** 53 | * 可选值: ROTATE_RIGHT | ROTATE_LEFT | ZOOM_IN | ZOOM_OUT | SCALE_ORIGIN 54 | */ 55 | public function key($value = '') 56 | { 57 | return $this->set('key', $value); 58 | } 59 | 60 | /** 61 | * 62 | */ 63 | public function label($value = '') 64 | { 65 | return $this->set('label', $value); 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Pagination-7hQWoF5V.js: -------------------------------------------------------------------------------- 1 | import{t as f,w as c,x as v,G as P,H as m,l,b2 as b,z as y,D as h,Q as _,T as g,E as N,a4 as C}from"./index-CEmnTf-r.js";var x=function(n){f(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t.prototype.formatNumber=function(e,r){var a=void 0;return typeof e=="string"?(e=c(e)?v(e,this.props.data):e,a=typeof e=="string"?parseInt(e,10):e):typeof e=="number"&&(a=e),typeof a=="number"&&!isNaN(a)?a:r},t.prototype.onPageChange=function(e,r,a){return P(this,void 0,void 0,function(){var i,o,s,u,p;return m(this,function(d){switch(d.label){case 0:return i=this.props,o=i.onPageChange,s=i.dispatchEvent,u=i.data,[4,s==null?void 0:s("change",C(u,{page:e,perPage:r}))];case 1:return p=d.sent(),p!=null&&p.prevented?[2]:(o==null||o(e,r,a),[2])}})})},t.prototype.render=function(){var e=this.props,r=e.maxButtons,a=e.activePage,i=e.total,o=e.perPage;return l.createElement(b,y({},this.props,{onPageChange:this.onPageChange,maxButtons:this.formatNumber(r),activePage:this.formatNumber(a),total:this.formatNumber(i),perPage:this.formatNumber(o)}))},h([_,g("design:type",Function),g("design:paramtypes",[Number,Number,String]),g("design:returntype",Promise)],t.prototype,"onPageChange",null),t}(l.Component),R=function(n){f(t,n);function t(){return n!==null&&n.apply(this,arguments)||this}return t=h([N({type:"pagination",alias:["pager"],name:"pagination"})],t),t}(x);export{R as PaginationRenderer,x as default}; 2 | -------------------------------------------------------------------------------- /src/Models/AdminApi.php: -------------------------------------------------------------------------------- 1 | 'json', 17 | ]; 18 | 19 | const METHODS = ['get', 'head', 'post', 'put', 'patch', 'delete', 'options']; 20 | 21 | public function templateTitle(): Attribute 22 | { 23 | return Attribute::get(function () { 24 | if (!class_exists($this->template)) return ''; 25 | 26 | if (!(new \ReflectionClass($this->template))->isSubclassOf(AdminBaseApi::class)) return ''; 27 | 28 | $api = app($this->template); 29 | 30 | return $api->getMethod() . ' - ' . $api->getTitle(); 31 | }); 32 | } 33 | 34 | public function method(): Attribute 35 | { 36 | return Attribute::get(function () { 37 | if (!class_exists($this->template)) return ''; 38 | 39 | if (!(new \ReflectionClass($this->template))->isSubclassOf(AdminBaseApi::class)) return 'any'; 40 | 41 | $method = app($this->template)->getMethod(); 42 | 43 | return in_array($method, self::METHODS) ? $method : 'any'; 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /admin-views/src/layouts/TopLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import {Layout} from 'antd' 2 | import LayoutLogo from '@/layouts/components/LayoutLogo' 3 | import LayoutContent from '@/layouts/components/LayoutContent' 4 | import LayoutTopBar from '@/layouts/components/LayoutTopBar' 5 | import useSetting from '@/hooks/useSetting' 6 | import LayoutTopMenu from '@/layouts/components/LayoutMenu/top' 7 | 8 | const {Header, Content} = Layout 9 | 10 | // 顶部布局 11 | const TopLayout = () => { 12 | const {getSetting} = useSetting() 13 | 14 | const darkTop = () => { 15 | return getSetting('system_theme_setting.topTheme') == 'dark' && !getSetting('system_theme_setting.darkTheme') 16 | } 17 | 18 | const border = darkTop() ? '' : 'border-b' 19 | 20 | return ( 21 | 22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 | 30 |
31 | 32 | 33 | 34 |
35 | ) 36 | } 37 | 38 | export default TopLayout 39 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slowlyo/owl-admin", 3 | "description": "基于 laravel、amis 开发的后台框架~", 4 | "license": "MIT", 5 | "authors": [ 6 | { 7 | "name": "slowlyo", 8 | "email": "slowlyo_email@qq.com", 9 | "homepage": "https://github.com/slowlyo" 10 | } 11 | ], 12 | "homepage": "https://github.com/slowlyo/owl-admin", 13 | "support": { 14 | "email": "slowlyo_email@qq.com", 15 | "issues": "https://github.com/Slowlyo/owl-admin/issues", 16 | "forum": "https://github.com/orgs/owl-admin/discussions", 17 | "wiki": "https://doc.owladmin.com/" 18 | }, 19 | "keywords": [ 20 | "laravel", 21 | "owl-admin", 22 | "admin", 23 | "amis" 24 | ], 25 | "require": { 26 | "php": ">=8.2", 27 | "illuminate/support": ">=11", 28 | "slowlyo/laravel-support": "*", 29 | "ext-zip": "*", 30 | "ext-gd": "*" 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "Slowlyo\\OwlAdmin\\": "src/" 35 | }, 36 | "files": [ 37 | "src/Support/helpers.php" 38 | ] 39 | }, 40 | "extra": { 41 | "laravel": { 42 | "providers": [ 43 | "Slowlyo\\OwlAdmin\\AdminServiceProvider" 44 | ], 45 | "aliases": { 46 | "OwlAdmin": "Slowlyo\\OwlAdmin\\Facades\\OwlAdmin" 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Support/Apis/DataCreateApi.php: -------------------------------------------------------------------------------- 1 | service()->store(request()->all()); 22 | 23 | if ($result) { 24 | return Admin::response() 25 | ->successMessage(admin_trans('admin.successfully_message', ['attribute' => admin_trans('admin.create')])); 26 | } 27 | 28 | return Admin::response()->fail(admin_trans('admin.failed_message', ['attribute' => admin_trans('admin.create')])); 29 | } 30 | 31 | public function argsSchema() 32 | { 33 | return [ 34 | amis()->SelectControl('model', admin_trans('admin.relationships.model')) 35 | ->required() 36 | ->menuTpl('${label} ${table}') 37 | ->source('/dev_tools/relation/model_options') 38 | ->searchable(), 39 | ]; 40 | } 41 | 42 | protected function service() 43 | { 44 | $service = $this->blankService(); 45 | 46 | $service->setModelName($this->getArgs('model')); 47 | 48 | return $service; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /admin-views/dist/assets/InputVerificationCode-BgRKI8ob.js: -------------------------------------------------------------------------------- 1 | import{t as g,G as h,H as l,l as f,d6 as C,z as u,x as y,D as p,Q as v,T as s,a2 as m}from"./index-CEmnTf-r.js";var _=function(e){g(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.onFinish=function(r){return h(this,void 0,void 0,function(){var n,i,d,o;return l(this,function(a){switch(a.label){case 0:return n=this.props,i=n.dispatchEvent,d=n.data,[4,i("finish",u(u({},d),{value:r}),this)];case 1:return o=a.sent(),o!=null&&o.prevented?[2]:[2]}})})},t.prototype.onChange=function(r){return h(this,void 0,void 0,function(){var n,i,d,o,a;return l(this,function(c){switch(c.label){case 0:return n=this.props,i=n.onChange,d=n.data,o=n.dispatchEvent,[4,o("change",u(u({},d),{value:r}))];case 1:return a=c.sent(),a!=null&&a.prevented?[2]:(i==null||i(r),[2])}})})},t.prototype.render=function(){var r=this.props.separator;return f.createElement(C,u({},this.props,{separator:typeof r=="string"?function(n){return y(r,n)}:function(){},onFinish:this.onFinish,onChange:this.onChange}))},p([v,s("design:type",Function),s("design:paramtypes",[String]),s("design:returntype",Promise)],t.prototype,"onFinish",null),p([v,s("design:type",Function),s("design:paramtypes",[String]),s("design:returntype",Promise)],t.prototype,"onChange",null),t}(f.Component),E=function(e){g(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t=p([m({type:"input-verification-code"})],t),t}(_);export{E as VerificationCodeControlRenderer,_ as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/pla-CjnFlu4u.js: -------------------------------------------------------------------------------- 1 | var e={comments:{lineComment:"#"},brackets:[["[","]"],["<",">"],["(",")"]],autoClosingPairs:[{open:"[",close:"]"},{open:"<",close:">"},{open:"(",close:")"}],surroundingPairs:[{open:"[",close:"]"},{open:"<",close:">"},{open:"(",close:")"}]},o={defaultToken:"",tokenPostfix:".pla",brackets:[{open:"[",close:"]",token:"delimiter.square"},{open:"<",close:">",token:"delimiter.angle"},{open:"(",close:")",token:"delimiter.parenthesis"}],keywords:[".i",".o",".mv",".ilb",".ob",".label",".type",".phase",".pair",".symbolic",".symbolic-output",".kiss",".p",".e",".end"],comment:/#.*$/,identifier:/[a-zA-Z]+[a-zA-Z0-9_\-]*/,plaContent:/[01\-~\|]+/,tokenizer:{root:[{include:"@whitespace"},[/@comment/,"comment"],[/\.([a-zA-Z_\-]+)/,{cases:{"@eos":{token:"keyword.$1"},"@keywords":{cases:{".type":{token:"keyword.$1",next:"@type"},"@default":{token:"keyword.$1",next:"@keywordArg"}}},"@default":{token:"keyword.$1"}}}],[/@identifier/,"identifier"],[/@plaContent/,"string"]],whitespace:[[/[ \t\r\n]+/,""]],type:[{include:"@whitespace"},[/\w+/,{token:"type",next:"@pop"}]],keywordArg:[[/[ \t\r\n]+/,{cases:{"@eos":{token:"",next:"@pop"},"@default":""}}],[/@comment/,"comment","@pop"],[/[<>()\[\]]/,{cases:{"@eos":{token:"@brackets",next:"@pop"},"@default":"@brackets"}}],[/\-?\d+/,{cases:{"@eos":{token:"number",next:"@pop"},"@default":"number"}}],[/@identifier/,{cases:{"@eos":{token:"identifier",next:"@pop"},"@default":"identifier"}}],[/[;=]/,{cases:{"@eos":{token:"delimiter",next:"@pop"},"@default":"delimiter"}}]]}};export{e as conf,o as language}; 2 | -------------------------------------------------------------------------------- /src/Support/Cores/Api.php: -------------------------------------------------------------------------------- 1 | set('apis', [ 21 | DataListApi::class, 22 | DataCreateApi::class, 23 | DataDetailApi::class, 24 | DataDeleteApi::class, 25 | DataUpdateApi::class, 26 | OptionsApi::class, 27 | GetSettingsApi::class, 28 | SaveSettingsApi::class, 29 | ]); 30 | 31 | if (!is_dir(self::path())) return; 32 | 33 | collect(scandir(app_path('/ApiTemplates'))) 34 | ->filter(fn($file) => !in_array($file, ['.', '..']) && str_ends_with($file, '.php')) 35 | ->each(function ($file) { 36 | $class = 'App\\ApiTemplates\\' . str_replace('.php', '', $file); 37 | try { 38 | if (class_exists($class)) { 39 | Admin::context()->add('apis', $class); 40 | } 41 | } catch (\Throwable $e) { 42 | } 43 | }); 44 | } 45 | 46 | public static function path($file = '') 47 | { 48 | return app_path('/ApiTemplates') . ($file ? '/' . ltrim($file, '/') : ''); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Console/CreateUserCommand.php: -------------------------------------------------------------------------------- 1 | ask('Please enter a username to login'); 31 | 32 | $password = bcrypt($this->secret('Please enter a password to login')); 33 | 34 | $name = $this->ask('Please enter a name to display'); 35 | 36 | $roles = AdminRole::all(); 37 | 38 | /** @var array $selected */ 39 | $selected = 40 | $this->choice('Please choose a role for the user', $roles->pluck('name')->toArray(), null, null, true); 41 | 42 | $roles = $roles->filter(function ($role) use ($selected) { 43 | return in_array($role->name, $selected); 44 | }); 45 | 46 | $user = new AdminUser(compact('username', 'password', 'name')); 47 | 48 | $user->save(); 49 | 50 | $user->roles()->attach($roles); 51 | 52 | $this->info("User [$name] created successfully."); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Support/Apis/OptionsApi.php: -------------------------------------------------------------------------------- 1 | service()->query()->get([ 19 | $this->getArgs('value_field') . ' as value', 20 | $this->getArgs('label_field') . ' as label', 21 | ]); 22 | 23 | return Admin::response()->success($data); 24 | } 25 | 26 | public function argsSchema() 27 | { 28 | return [ 29 | amis() 30 | ->SelectControl('model', __('admin.relationships.model')) 31 | ->required() 32 | ->menuTpl('${label} ${table}') 33 | ->source('/dev_tools/relation/model_options') 34 | ->searchable(), 35 | amis() 36 | ->TextControl('value_field', 'Value 字段') 37 | ->source('/dev_tools/relation/column_options?model=${model}'), 38 | amis() 39 | ->TextControl('label_field', 'Label 字段') 40 | ->source('/dev_tools/relation/column_options?model=${model}'), 41 | ]; 42 | } 43 | 44 | protected function service() 45 | { 46 | $service = $this->blankService(); 47 | 48 | $service->setModelName($this->getArgs('model')); 49 | 50 | return $service; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Support/Apis/GetSettingsApi.php: -------------------------------------------------------------------------------- 1 | getArgs('mode')) { 19 | 'all' => settings()->all(), 20 | 'part' => collect(settings()->all())->filter(fn($_, $k) => in_array($k, $this->getArgs('keys')))->toArray(), 21 | 'one' => settings()->get($this->getArgs('key')), 22 | }; 23 | 24 | return Admin::response()->success($data); 25 | } 26 | 27 | public function argsSchema() 28 | { 29 | $allKeys = collect(settings()->all())->keys()->map(fn($i) => [ 30 | 'value' => $i, 31 | 'label' => $i, 32 | ])->toArray(); 33 | 34 | return [ 35 | amis()->RadiosControl('mode', '获取模式')->options([ 36 | ['value' => 'all', 'label' => '所有'], 37 | ['value' => 'part', 'label' => '部分'], 38 | ['value' => 'one', 'label' => '单个'], 39 | ])->selectFirst(), 40 | amis()->TextControl('key', '设置项')->required()->visibleOn('${mode == "one"}')->options($allKeys), 41 | amis()->ArrayControl('keys', '设置项')->required()->visibleOn('${mode == "part"}')->items([ 42 | amis()->TextControl('value')->required()->options($allKeys), 43 | ]), 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /admin-views/dist/assets/scheme-Dhb-2j9p.js: -------------------------------------------------------------------------------- 1 | var e={comments:{lineComment:";",blockComment:["#|","|#"]},brackets:[["(",")"],["{","}"],["[","]"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'}]},o={defaultToken:"",ignoreCase:!0,tokenPostfix:".scheme",brackets:[{open:"(",close:")",token:"delimiter.parenthesis"},{open:"{",close:"}",token:"delimiter.curly"},{open:"[",close:"]",token:"delimiter.square"}],keywords:["case","do","let","loop","if","else","when","cons","car","cdr","cond","lambda","lambda*","syntax-rules","format","set!","quote","eval","append","list","list?","member?","load"],constants:["#t","#f"],operators:["eq?","eqv?","equal?","and","or","not","null?"],tokenizer:{root:[[/#[xXoObB][0-9a-fA-F]+/,"number.hex"],[/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?/,"number.float"],[/(?:\b(?:(define|define-syntax|define-macro))\b)(\s+)((?:\w|\-|\!|\?)*)/,["keyword","white","variable"]],{include:"@whitespace"},{include:"@strings"},[/[a-zA-Z_#][a-zA-Z0-9_\-\?\!\*]*/,{cases:{"@keywords":"keyword","@constants":"constant","@operators":"operators","@default":"identifier"}}]],comment:[[/[^\|#]+/,"comment"],[/#\|/,"comment","@push"],[/\|#/,"comment","@pop"],[/[\|#]/,"comment"]],whitespace:[[/[ \t\r\n]+/,"white"],[/#\|/,"comment","@comment"],[/;.*$/,"comment"]],strings:[[/"$/,"string","@popall"],[/"(?=.)/,"string","@multiLineString"]],multiLineString:[[/[^\\"]+$/,"string","@popall"],[/[^\\"]+/,"string"],[/\\./,"string.escape"],[/"/,"string","@popall"],[/\\$/,"string"]]}};export{e as conf,o as language}; 2 | -------------------------------------------------------------------------------- /src/Support/Apis/DataDeleteApi.php: -------------------------------------------------------------------------------- 1 | service()->delete(request($this->getArgs('primary_key', 'ids'))); 22 | 23 | if ($result) { 24 | return Admin::response() 25 | ->successMessage(admin_trans('admin.successfully_message', ['attribute' => admin_trans('admin.delete')])); 26 | } 27 | 28 | return Admin::response()->fail(admin_trans('admin.failed_message', ['attribute' => admin_trans('admin.delete')])); 29 | } 30 | 31 | public function argsSchema() 32 | { 33 | return [ 34 | amis()->SelectControl('model', admin_trans('admin.relationships.model')) 35 | ->required() 36 | ->menuTpl('${label} ${table}') 37 | ->source('/dev_tools/relation/model_options') 38 | ->searchable(), 39 | amis()->TextControl('primary_id', admin_trans('admin.code_generators.primary_key'))->value('ids'), 40 | ]; 41 | } 42 | 43 | protected function service() 44 | { 45 | $service = $this->blankService(); 46 | 47 | $service->setModelName($this->getArgs('model')); 48 | 49 | return $service; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Support/Apis/DataUpdateApi.php: -------------------------------------------------------------------------------- 1 | service()->update(request($this->getArgs('primary_key', 'id')), request()->all()); 22 | 23 | if ($result) { 24 | return Admin::response() 25 | ->successMessage(admin_trans('admin.successfully_message', ['attribute' => admin_trans('admin.save')])); 26 | } 27 | 28 | return Admin::response()->fail(admin_trans('admin.failed_message', ['attribute' => admin_trans('admin.save')])); 29 | } 30 | 31 | public function argsSchema() 32 | { 33 | return [ 34 | amis()->SelectControl('model', admin_trans('admin.relationships.model')) 35 | ->required() 36 | ->menuTpl('${label} ${table}') 37 | ->source('/dev_tools/relation/model_options') 38 | ->searchable(), 39 | amis()->TextControl('primary_id', admin_trans('admin.code_generators.primary_key'))->value('id'), 40 | ]; 41 | } 42 | 43 | protected function service() 44 | { 45 | $service = $this->blankService(); 46 | 47 | $service->setModelName($this->getArgs('model')); 48 | 49 | return $service; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /admin-views/dist/assets/Plain-D0Ub5Iv4.js: -------------------------------------------------------------------------------- 1 | import{t as v,a4 as l,aq as C,l as d,L as M,D as o,Q as c,T as a,E as _}from"./index-CEmnTf-r.js";var x=function(i){v(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return t.prototype.handleClick=function(e){var n=this.props,r=n.dispatchEvent,s=n.data;r("click",l(s,{nativeEvent:e}))},t.prototype.handleMouseEnter=function(e){var n=this.props,r=n.dispatchEvent,s=n.data;r(e,l(s,{nativeEvent:e}))},t.prototype.handleMouseLeave=function(e){var n=this.props,r=n.dispatchEvent,s=n.data;r(e,l(s,{nativeEvent:e}))},t.prototype.render=function(){var e=this.props,n=e.className,r=e.style,s=e.wrapperComponent,u=e.text,y=e.data,h=e.tpl,m=e.inline,E=e.placeholder,f=e.classnames,p=C(this.props),g=s||(m?"span":"div");return d.createElement(g,{className:f("PlainField",n),style:r,onClick:this.handleClick,onMouseEnter:this.handleMouseEnter,onMouseLeave:this.handleMouseLeave},h||u?M(h||u,y):typeof p>"u"||p===""||p===null?d.createElement("span",{className:"text-muted"},E):String(p))},t.defaultProps={wrapperComponent:"",inline:!0,placeholder:"-"},o([c,a("design:type",Function),a("design:paramtypes",[Object]),a("design:returntype",void 0)],t.prototype,"handleClick",null),o([c,a("design:type",Function),a("design:paramtypes",[Object]),a("design:returntype",void 0)],t.prototype,"handleMouseEnter",null),o([c,a("design:type",Function),a("design:paramtypes",[Object]),a("design:returntype",void 0)],t.prototype,"handleMouseLeave",null),t}(d.Component),b=function(i){v(t,i);function t(){return i!==null&&i.apply(this,arguments)||this}return t=o([_({type:"plain",alias:["text"],name:"plain"})],t),t}(x);export{x as Plain,b as PlainRenderer}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/InputMonthRange-nwM7f3hr.js: -------------------------------------------------------------------------------- 1 | import{t as g,v as R,l as h,ag as M,c5 as _,z as I,ai as v,c6 as D,D as F,ap as P,T as m,a2 as b}from"./index-CEmnTf-r.js";import E from"./InputDateRange-PxuYfEfI.js";var N=function(e){g(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.render=function(){var a=this.props,x=a.className;a.style;var l=a.classPrefix,u=a.minDate,d=a.maxDate,p=a.minDuration,c=a.maxDuration,o=a.data,r=a.format,f=a.mobileUI,i=a.valueFormat,y=a.inputFormat,C=a.displayFormat,n=a.env,s=R(a,["className","style","classPrefix","minDate","maxDate","minDuration","maxDuration","data","format","mobileUI","valueFormat","inputFormat","displayFormat","env"]);return h.createElement("div",{className:M("".concat(l,"DateRangeControl"),x)},h.createElement(_,I({viewMode:"months",mobileUI:f,valueFormat:i||r,displayFormat:C||y,classPrefix:l,popOverContainer:f?n==null?void 0:n.getModalContainer:s.popOverContainer||n.getModalContainer,popOverContainerSelector:s.popOverContainerSelector,onRef:this.getRef,data:o},s,{minDate:u?v(u,o,i||r):void 0,maxDate:d?v(d,o,i||r):void 0,minDuration:p?D(p):void 0,maxDuration:c?D(c):void 0,onChange:this.handleChange,onFocus:this.dispatchEvent,onBlur:this.dispatchEvent})))},F([P(),m("design:type",Function),m("design:paramtypes",[]),m("design:returntype",void 0)],t.prototype,"render",null),t}(E),Y=function(e){g(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.defaultProps={format:"X",inputFormat:"YYYY-MM",joinValues:!0,delimiter:",",ranges:"",shortcuts:"thismonth,prevmonth",animation:!0},t=F([b({type:"input-month-range"})],t),t}(N);export{Y as MonthRangeControlRenderer,N as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/InputYearRange-hjSYvO0Y.js: -------------------------------------------------------------------------------- 1 | import{t as y,v as R,l as f,ag as _,c5 as Y,z as I,ai as D,c6 as g,D as h,ap as P,T as m,a2 as b}from"./index-CEmnTf-r.js";import E from"./InputDateRange-PxuYfEfI.js";var N=function(t){y(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.prototype.render=function(){var a=this.props,F=a.className;a.style;var l=a.classPrefix,u=a.minDate,d=a.maxDate,p=a.minDuration,c=a.maxDuration,r=a.data,o=a.format,v=a.mobileUI,i=a.valueFormat,x=a.inputFormat,C=a.displayFormat,n=a.env,s=R(a,["className","style","classPrefix","minDate","maxDate","minDuration","maxDuration","data","format","mobileUI","valueFormat","inputFormat","displayFormat","env"]);return f.createElement("div",{className:_("".concat(l,"DateRangeControl"),F)},f.createElement(Y,I({viewMode:"years",mobileUI:v,valueFormat:i||o,displayFormat:C||x,classPrefix:l,popOverContainer:v?n==null?void 0:n.getModalContainer:s.popOverContainer||n.getModalContainer,popOverContainerSelector:s.popOverContainerSelector,onRef:this.getRef,data:r},s,{minDate:u?D(u,r,i||o):void 0,maxDate:d?D(d,r,i||o):void 0,minDuration:p?g(p):void 0,maxDuration:c?g(c):void 0,onChange:this.handleChange,onFocus:this.dispatchEvent,onBlur:this.dispatchEvent})))},h([P(),m("design:type",Function),m("design:paramtypes",[]),m("design:returntype",void 0)],e.prototype,"render",null),e}(E),M=function(t){y(e,t);function e(){return t!==null&&t.apply(this,arguments)||this}return e.defaultProps={format:"X",inputFormat:"YYYY",joinValues:!0,delimiter:",",ranges:"thisyear,prevyear",shortcuts:"thisyear,prevyear",animation:!0},e=h([b({type:"input-year-range"})],e),e}(N);export{M as YearRangeControlRenderer,N as default}; 2 | -------------------------------------------------------------------------------- /admin-views/dist/assets/flow9-Cac8vKd7.js: -------------------------------------------------------------------------------- 1 | var e={comments:{blockComment:["/*","*/"],lineComment:"//"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}",notIn:["string"]},{open:"[",close:"]",notIn:["string"]},{open:"(",close:")",notIn:["string"]},{open:'"',close:'"',notIn:["string"]},{open:"'",close:"'",notIn:["string"]}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"<",close:">"}]},o={defaultToken:"",tokenPostfix:".flow",keywords:["import","require","export","forbid","native","if","else","cast","unsafe","switch","default"],types:["io","mutable","bool","int","double","string","flow","void","ref","true","false","with"],operators:["=",">","<","<=",">=","==","!","!=",":=","::=","&&","||","+","-","*","/","@","&","%",":","->","\\","$","??","^"],symbols:/[@$=>](?!@symbols)/,"delimiter"],[/@symbols/,{cases:{"@operators":"delimiter","@default":""}}],[/((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,"string","@string"]],whitespace:[[/[ \t\r\n]+/,""],[/\/\*/,"comment","@comment"],[/\/\/.*$/,"comment"]],comment:[[/[^\/*]+/,"comment"],[/\*\//,"comment","@pop"],[/[\/*]/,"comment"]],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,"string","@pop"]]}};export{e as conf,o as language}; 2 | --------------------------------------------------------------------------------