├── .example.env
├── .gitattributes
├── .gitignore
├── LICENSE
├── LICENSE.txt
├── README.md
├── SECURITY.md
├── app
├── .htaccess
├── AppService.php
├── ExceptionHandle.php
├── admin
│ ├── common.php
│ ├── config
│ │ ├── admin.php
│ │ ├── app.php
│ │ ├── captcha.php
│ │ └── view.php
│ ├── controller
│ │ ├── AdminBaseController.php
│ │ ├── AdminLogController.php
│ │ ├── AdminMenuController.php
│ │ ├── AdminRoleController.php
│ │ ├── AdminUserController.php
│ │ ├── AuthController.php
│ │ ├── DatabaseController.php
│ │ ├── ErrorController.php
│ │ ├── FileController.php
│ │ ├── GenerateController.php
│ │ ├── IndexController.php
│ │ ├── SettingController.php
│ │ ├── SettingGroupController.php
│ │ ├── TestController.php
│ │ ├── UserController.php
│ │ └── UserLevelController.php
│ ├── event.php
│ ├── exception
│ │ └── AdminServiceException.php
│ ├── listener
│ │ ├── AdminUserLogin.php
│ │ └── AdminUserLogout.php
│ ├── middleware.php
│ ├── model
│ │ ├── AdminBaseModel.php
│ │ ├── AdminLog.php
│ │ ├── AdminLogData.php
│ │ ├── AdminMenu.php
│ │ ├── AdminRole.php
│ │ └── AdminUser.php
│ ├── provider.php
│ ├── service
│ │ ├── AdminBaseService.php
│ │ ├── AdminLogService.php
│ │ ├── AdminRoleService.php
│ │ ├── AdminUserService.php
│ │ ├── AuthService.php
│ │ └── PageService.php
│ ├── traits
│ │ ├── AdminAuthTrait.php
│ │ ├── AdminPhpOffice.php
│ │ ├── AdminSettingForm.php
│ │ ├── AdminTreeTrait.php
│ │ └── SettingContent.php
│ ├── validate
│ │ ├── AdminBaseValidate.php
│ │ ├── AdminMenuValidate.php
│ │ ├── AdminRoleValidate.php
│ │ └── AdminUserValidate.php
│ └── view
│ │ ├── admin_log
│ │ ├── detail.html
│ │ └── index.html
│ │ ├── admin_menu
│ │ ├── add.html
│ │ └── index.html
│ │ ├── admin_role
│ │ ├── access.html
│ │ ├── add.html
│ │ └── index.html
│ │ ├── admin_user
│ │ ├── add.html
│ │ ├── index.html
│ │ └── profile.html
│ │ ├── auth
│ │ ├── captcha.html
│ │ ├── gee_test.html
│ │ ├── login.html
│ │ └── login_bg.html
│ │ ├── database
│ │ ├── table.html
│ │ └── view.html
│ │ ├── error
│ │ ├── 403.html
│ │ ├── 404.html
│ │ └── 500.html
│ │ ├── file
│ │ ├── index.html
│ │ └── upload.html
│ │ ├── generate
│ │ ├── add.html
│ │ ├── css.html
│ │ ├── form.html
│ │ ├── index.html
│ │ └── template.html
│ │ ├── index
│ │ ├── chart1.html
│ │ ├── chart2.html
│ │ ├── chart3.html
│ │ ├── index.html
│ │ ├── top_widget1.html
│ │ └── top_widget2.html
│ │ ├── public
│ │ ├── base.html
│ │ ├── change_page.html
│ │ ├── content_header.html
│ │ ├── control_sidebar.html
│ │ ├── footer.html
│ │ ├── head_css.html
│ │ ├── head_js.html
│ │ ├── layer_base.html
│ │ ├── navbar
│ │ │ ├── message.html
│ │ │ ├── nav.html
│ │ │ ├── navbar.html
│ │ │ ├── notification.html
│ │ │ ├── search_form.html
│ │ │ ├── sidebar_button.html
│ │ │ └── user_menu.html
│ │ └── sidebar.html
│ │ ├── setting
│ │ ├── add.html
│ │ ├── all.html
│ │ ├── config_type.html
│ │ ├── index.html
│ │ └── show.html
│ │ ├── setting_group
│ │ ├── add.html
│ │ └── index.html
│ │ ├── template
│ │ ├── content.html
│ │ └── layer_content.html
│ │ ├── test
│ │ ├── add.html
│ │ └── index.html
│ │ ├── user
│ │ ├── add.html
│ │ └── index.html
│ │ └── user_level
│ │ ├── add.html
│ │ └── index.html
├── api
│ ├── common.php
│ ├── config
│ │ └── api.php
│ ├── controller
│ │ ├── ApiBaseController.php
│ │ ├── AuthController.php
│ │ ├── IndexController.php
│ │ ├── TestController.php
│ │ ├── TokenController.php
│ │ ├── UserController.php
│ │ └── UserLevelController.php
│ ├── exception
│ │ └── ApiServiceException.php
│ ├── middleware.php
│ ├── middleware
│ │ └── AllowCrossDomain.php
│ ├── service
│ │ ├── ApiBaseService.php
│ │ ├── AuthService.php
│ │ ├── TestService.php
│ │ ├── TokenService.php
│ │ ├── UserLevelService.php
│ │ └── UserService.php
│ └── traits
│ │ ├── ApiAuthTrait.php
│ │ └── ApiThrottleTrait.php
├── command
│ ├── GenerateAppKey.php
│ ├── GenerateJwtKey.php
│ ├── InitEnv.php
│ ├── ResetAdminPassword.php
│ └── Test.php
├── common.php
├── common
│ ├── exception
│ │ ├── CommonServiceException.php
│ │ └── tpl
│ │ │ └── think_exception.tpl
│ ├── model
│ │ ├── CommonBaseModel.php
│ │ ├── Setting.php
│ │ ├── SettingGroup.php
│ │ ├── Test.php
│ │ ├── User.php
│ │ └── UserLevel.php
│ ├── service
│ │ ├── CommonBaseService.php
│ │ ├── DateService.php
│ │ └── StringService.php
│ └── validate
│ │ ├── CommonBaseValidate.php
│ │ ├── SettingGroupValidate.php
│ │ ├── SettingValidate.php
│ │ ├── TestValidate.php
│ │ ├── UserLevelValidate.php
│ │ └── UserValidate.php
├── event.php
├── index
│ ├── common.php
│ ├── config
│ │ └── view.php
│ ├── controller
│ │ ├── AuthController.php
│ │ ├── IndexBaseController.php
│ │ ├── IndexController.php
│ │ └── UserController.php
│ ├── exception
│ │ └── IndexServiceException.php
│ ├── middleware.php
│ ├── service
│ │ ├── AuthService.php
│ │ └── IndexBaseService.php
│ ├── traits
│ │ └── IndexAuthTrait.php
│ └── view
│ │ ├── auth
│ │ └── login.html
│ │ ├── index
│ │ ├── about.html
│ │ ├── index.html
│ │ └── product.html
│ │ └── user
│ │ └── index.html
├── middleware.php
├── provider.php
└── service.php
├── composer.json
├── config
├── app.php
├── cache.php
├── captcha.php
├── console.php
├── cookie.php
├── database.php
├── filesystem.php
├── lang.php
├── log.php
├── map.php
├── middleware.php
├── route.php
├── session.php
├── trace.php
└── view.php
├── database
├── example
│ └── README.md
└── migrations
│ ├── 20191001081329_setting.php
│ ├── 20191001081340_setting_group.php
│ ├── 20200804023050_admin_user.php
│ ├── 20200806095505_admin_menu.php
│ ├── 20200806100423_admin_role.php
│ ├── 20200806100513_admin_log.php
│ ├── 20200806100516_admin_log_data.php
│ ├── 20200827064827_user.php
│ ├── 20210219080541_user_level.php
│ └── 20210908031808_test.php
├── extend
├── generate
│ ├── AdminControllerBuild.php
│ ├── AdminMenuBuild.php
│ ├── AdminViewBuild.php
│ ├── ApiControllerBuild.php
│ ├── ApiServiceBuild.php
│ ├── Build.php
│ ├── Generate.php
│ ├── ModelBuild.php
│ ├── ValidateBuild.php
│ ├── exception
│ │ └── GenerateException.php
│ ├── field
│ │ ├── Color.php
│ │ ├── Date.php
│ │ ├── DateRange.php
│ │ ├── Datetime.php
│ │ ├── DatetimeRange.php
│ │ ├── Editor.php
│ │ ├── Email.php
│ │ ├── Field.php
│ │ ├── File.php
│ │ ├── Icon.php
│ │ ├── IdCard.php
│ │ ├── Image.php
│ │ ├── Ip.php
│ │ ├── Map.php
│ │ ├── Mobile.php
│ │ ├── MultiFile.php
│ │ ├── MultiImage.php
│ │ ├── MultiSelect.php
│ │ ├── Number.php
│ │ ├── Password.php
│ │ ├── Select.php
│ │ ├── SwitchField.php
│ │ ├── Text.php
│ │ ├── Textarea.php
│ │ ├── Time.php
│ │ ├── TimeRange.php
│ │ ├── Url.php
│ │ ├── Video.php
│ │ ├── Year.php
│ │ ├── YearMonth.php
│ │ ├── YearMonthRange.php
│ │ └── YearRange.php
│ ├── stub
│ │ ├── admin_controller
│ │ │ ├── AdminController.stub
│ │ │ ├── action_add.stub
│ │ │ ├── action_del.stub
│ │ │ ├── action_disable.stub
│ │ │ ├── action_edit.stub
│ │ │ ├── action_enable.stub
│ │ │ ├── action_export.stub
│ │ │ ├── action_import.stub
│ │ │ ├── action_index.stub
│ │ │ ├── relation_assign_1.stub
│ │ │ ├── relation_data_list.stub
│ │ │ ├── relation_delete.stub
│ │ │ └── relation_with.stub
│ │ ├── admin_view
│ │ │ ├── add
│ │ │ │ ├── add.stub
│ │ │ │ ├── customer_multi_select_data.stub
│ │ │ │ ├── customer_select_data.stub
│ │ │ │ └── relation_select_data.stub
│ │ │ └── index
│ │ │ │ ├── create.stub
│ │ │ │ ├── del1.stub
│ │ │ │ ├── del2.stub
│ │ │ │ ├── enable1.stub
│ │ │ │ ├── enable2.stub
│ │ │ │ ├── export.stub
│ │ │ │ ├── filter.stub
│ │ │ │ ├── import.stub
│ │ │ │ ├── index.stub
│ │ │ │ ├── refresh.stub
│ │ │ │ ├── select1.stub
│ │ │ │ ├── select2.stub
│ │ │ │ └── sort.stub
│ │ ├── api_controller
│ │ │ ├── ApiController.stub
│ │ │ ├── api_add.stub
│ │ │ ├── api_del.stub
│ │ │ ├── api_disable.stub
│ │ │ ├── api_edit.stub
│ │ │ ├── api_enable.stub
│ │ │ ├── api_index.stub
│ │ │ └── api_info.stub
│ │ ├── api_service
│ │ │ ├── ApiService.stub
│ │ │ ├── api_add.stub
│ │ │ ├── api_del.stub
│ │ │ ├── api_disable.stub
│ │ │ ├── api_edit.stub
│ │ │ ├── api_enable.stub
│ │ │ ├── api_index.stub
│ │ │ └── api_info.stub
│ │ ├── model
│ │ │ ├── Model.stub
│ │ │ ├── getter_setter_date.stub
│ │ │ ├── getter_setter_datetime.stub
│ │ │ ├── getter_setter_multi_select.stub
│ │ │ ├── getter_setter_select.stub
│ │ │ ├── getter_setter_switch.stub
│ │ │ └── relation.stub
│ │ └── validate
│ │ │ └── Validate.stub
│ ├── traits
│ │ ├── Tools.php
│ │ └── Tree.php
│ └── validate
│ │ ├── Color16.php
│ │ ├── ComplexPassword.php
│ │ ├── Email.php
│ │ ├── IdCard.php
│ │ ├── Ip.php
│ │ ├── Ipv4.php
│ │ ├── Ipv6.php
│ │ ├── MiddlePassword.php
│ │ ├── Mobile.php
│ │ ├── Number.php
│ │ ├── Number6.php
│ │ ├── Required.php
│ │ ├── Rule.php
│ │ ├── SimplePassword.php
│ │ └── Url.php
└── util
│ ├── geetest
│ └── GeeTest.php
│ ├── jwt
│ ├── Example.php
│ ├── Jwt.php
│ ├── JwtException.php
│ ├── README.md
│ ├── private.key
│ └── public.key
│ └── safe
│ └── SafeCookie.php
├── public
├── .htaccess
├── favicon.ico
├── index.php
├── robots.txt
├── router.php
├── static
│ ├── admin
│ │ ├── css
│ │ │ ├── access.css
│ │ │ ├── admin.css
│ │ │ └── adminlte.min.css
│ │ ├── images
│ │ │ ├── avatar.png
│ │ │ ├── login-default-bg.jpg
│ │ │ └── logo.png
│ │ ├── js
│ │ │ ├── admin.js
│ │ │ ├── adminlte.min.js
│ │ │ ├── requrest.js
│ │ │ ├── upload.js
│ │ │ └── validate.js
│ │ └── plugins
│ │ │ ├── bootstrap-colorpicker
│ │ │ ├── css
│ │ │ │ └── bootstrap-colorpicker.min.css
│ │ │ └── js
│ │ │ │ └── bootstrap-colorpicker.min.js
│ │ │ ├── bootstrap-number
│ │ │ └── bootstrap-number.min.js
│ │ │ ├── bootstrap-switch
│ │ │ ├── css
│ │ │ │ └── bootstrap3
│ │ │ │ │ └── bootstrap-switch.min.css
│ │ │ └── js
│ │ │ │ └── bootstrap-switch.min.js
│ │ │ ├── bootstrap
│ │ │ └── js
│ │ │ │ └── bootstrap.bundle.min.js
│ │ │ ├── bs-custom-file-input
│ │ │ └── bs-custom-file-input.min.js
│ │ │ ├── clipboard
│ │ │ └── clipboard.min.js
│ │ │ ├── echarts
│ │ │ └── echarts.simple.min.js
│ │ │ ├── fileinput
│ │ │ ├── css
│ │ │ │ ├── fileinput-rtl.min.css
│ │ │ │ └── fileinput.min.css
│ │ │ ├── img
│ │ │ │ ├── loading-sm.gif
│ │ │ │ └── loading.gif
│ │ │ ├── js
│ │ │ │ ├── fileinput.min.js
│ │ │ │ ├── locales
│ │ │ │ │ ├── LANG.js
│ │ │ │ │ ├── ja.js
│ │ │ │ │ ├── kr.js
│ │ │ │ │ ├── zh-TW.js
│ │ │ │ │ └── zh.js
│ │ │ │ └── plugins
│ │ │ │ │ ├── piexif.min.js
│ │ │ │ │ ├── purify.min.js
│ │ │ │ │ └── sortable.min.js
│ │ │ └── themes
│ │ │ │ ├── bs5
│ │ │ │ ├── theme.js
│ │ │ │ └── theme.min.js
│ │ │ │ ├── explorer-fa
│ │ │ │ ├── theme.css
│ │ │ │ ├── theme.js
│ │ │ │ ├── theme.min.css
│ │ │ │ └── theme.min.js
│ │ │ │ ├── explorer-fas
│ │ │ │ ├── theme.css
│ │ │ │ ├── theme.js
│ │ │ │ ├── theme.min.css
│ │ │ │ └── theme.min.js
│ │ │ │ ├── explorer
│ │ │ │ ├── theme.css
│ │ │ │ ├── theme.js
│ │ │ │ ├── theme.min.css
│ │ │ │ └── theme.min.js
│ │ │ │ ├── fa
│ │ │ │ ├── theme.js
│ │ │ │ └── theme.min.js
│ │ │ │ ├── fas
│ │ │ │ ├── theme.js
│ │ │ │ └── theme.min.js
│ │ │ │ └── gly
│ │ │ │ ├── theme.js
│ │ │ │ └── theme.min.js
│ │ │ ├── fontawesome-free
│ │ │ ├── css
│ │ │ │ └── all.min.css
│ │ │ └── webfonts
│ │ │ │ ├── fa-brands-400.woff2
│ │ │ │ ├── fa-regular-400.woff2
│ │ │ │ └── fa-solid-900.woff2
│ │ │ ├── fontawesome-iconpicker
│ │ │ ├── css
│ │ │ │ └── fontawesome-iconpicker.min.css
│ │ │ └── js
│ │ │ │ └── fontawesome-iconpicker.min.js
│ │ │ ├── gee-test
│ │ │ └── gee-test.min.js
│ │ │ ├── icheck-bootstrap
│ │ │ ├── LICENSE
│ │ │ └── icheck-bootstrap.min.css
│ │ │ ├── jquery-input-file-text
│ │ │ └── jquery-input-file-text.js
│ │ │ ├── jquery-pjax
│ │ │ └── jquery.pjax.js
│ │ │ ├── jquery-validation
│ │ │ ├── jquery.validate.min.js
│ │ │ └── localization
│ │ │ │ ├── messages_zh.min.js
│ │ │ │ └── messages_zh_TW.min.js
│ │ │ ├── jquery-viewer
│ │ │ └── jquery-viewer.min.js
│ │ │ ├── jquery
│ │ │ └── jquery.min.js
│ │ │ ├── js-cookie
│ │ │ └── js.cookie-2.2.0.min.js
│ │ │ ├── js-tree
│ │ │ ├── jstree.min.js
│ │ │ └── themes
│ │ │ │ ├── default-dark
│ │ │ │ ├── 32px.png
│ │ │ │ ├── 40px.png
│ │ │ │ ├── style.min.css
│ │ │ │ └── throbber.gif
│ │ │ │ └── default
│ │ │ │ ├── 32px.png
│ │ │ │ ├── 40px.png
│ │ │ │ ├── style.min.css
│ │ │ │ └── throbber.gif
│ │ │ ├── laydate
│ │ │ ├── laydate.js
│ │ │ └── theme
│ │ │ │ └── default
│ │ │ │ ├── font
│ │ │ │ ├── iconfont.eot
│ │ │ │ ├── iconfont.svg
│ │ │ │ ├── iconfont.ttf
│ │ │ │ └── iconfont.woff
│ │ │ │ └── laydate.css
│ │ │ ├── layer
│ │ │ ├── layer.js
│ │ │ ├── mobile
│ │ │ │ ├── layer.js
│ │ │ │ └── need
│ │ │ │ │ └── layer.css
│ │ │ └── theme
│ │ │ │ └── default
│ │ │ │ ├── icon-ext.png
│ │ │ │ ├── icon.png
│ │ │ │ ├── layer.css
│ │ │ │ ├── loading-0.gif
│ │ │ │ ├── loading-1.gif
│ │ │ │ └── loading-2.gif
│ │ │ ├── nprogress
│ │ │ ├── nprogress.css
│ │ │ └── nprogress.js
│ │ │ ├── pjax
│ │ │ └── jquery.pjax.js
│ │ │ ├── select2-bootstrap4-theme
│ │ │ └── select2-bootstrap4.min.css
│ │ │ ├── select2
│ │ │ ├── css
│ │ │ │ └── select2.min.css
│ │ │ └── js
│ │ │ │ ├── i18n
│ │ │ │ ├── en.js
│ │ │ │ ├── zh-CN.js
│ │ │ │ └── zh-TW.js
│ │ │ │ └── select2.min.js
│ │ │ ├── viewer
│ │ │ ├── viewer.min.css
│ │ │ └── viewer.min.js
│ │ │ └── wangEditor
│ │ │ └── wangEditor.min.js
│ └── index
│ │ ├── css
│ │ └── adminlte.min.css
│ │ ├── images
│ │ ├── avatar.png
│ │ └── user_level_default.png
│ │ ├── js
│ │ ├── adminlte.min.js
│ │ └── index.js
│ │ └── plugins
│ │ ├── bootstrap
│ │ └── js
│ │ │ └── bootstrap.bundle.min.js
│ │ ├── fontawesome-free
│ │ ├── css
│ │ │ └── all.min.css
│ │ └── webfonts
│ │ │ ├── fa-brands-400.woff2
│ │ │ ├── fa-regular-400.woff2
│ │ │ └── fa-solid-900.woff2
│ │ ├── icheck-bootstrap
│ │ ├── LICENSE
│ │ └── icheck-bootstrap.min.css
│ │ ├── jquery-validation
│ │ ├── jquery.validate.min.js
│ │ └── localization
│ │ │ └── messages_zh.min.js
│ │ ├── jquery
│ │ └── jquery.min.js
│ │ └── sweetalert2
│ │ ├── sweetalert2.all.min.js
│ │ └── sweetalert2.min.css
└── uploads
│ └── uploads
│ └── 20211105
│ ├── 09f88c2c15fd9ea2eaebefa94fc82519.png
│ ├── 393c19a1f90e320dde433eb064d0bc37.png
│ ├── 5606eb6dda163840c30eb58ba82bbfca.png
│ ├── 6c0ef20747bac6a8f0b1f75d78327806.jpg
│ ├── 943dafd0517fecce981b6e3c06e4ac87.png
│ ├── c8ef52b10a8b478f31bf8f2763b9478e.png
│ ├── d62acc7db724543cdab5635c03fa4bab.png
│ └── f5ffbf069f86c0bbeef12754c236c053.png
├── route
└── app.php
└── think
/.example.env:
--------------------------------------------------------------------------------
1 | APP_DEBUG=true
[APP]
DEFAULT_TIMEZONE=Asia/Shanghai
HOST=https://wwww.bearadmin.com
APP_KEY=
[DATABASE]
TYPE=mysql
HOSTNAME=127.0.0.1
DATABASE=bear_admin
USERNAME=root
PASSWORD=root
HOSTPORT=3306
CHARSET=utf8mb4
DEBUG=true
[CACHE]
DRIVER=file
[REDIS]
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_SELECT=0
[LANG]
default_lang=zh-cn
[FILESYSTEM]
driver=public
[API]
HTTP_CODE_SYNC=true
ALLOW_CROSS_DOMAIN=true
JWT_KEY=
JWT_EXP=3600
ENABLE_REFRESH_TOKEN=true
REFRESH_TOKEN_EXP=1296000
REUSE_CHECK=true
JWT_ISS=s
JWT_AUD=a
TOKEN_POSITION=header
TOKEN_FIELD=token
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=PHP
2 | *.css linguist-language=PHP
3 | *.html linguist-language=PHP
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | runtime
3 | .ENV
4 | composer.phar
5 | composer.lock
6 | Thumbs.db
7 | *.DS_Store
8 | .idea
9 | .vscode
10 | import
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
3 | 版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
4 | All rights reserved。
5 | ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
6 |
7 | Apache Licence是著名的非盈利开源组织Apache采用的协议。
8 | 该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
9 | 允许代码修改,再作为开源或商业软件发布。需要满足
10 | 的条件:
11 | 1. 需要给代码的用户一份Apache Licence ;
12 | 2. 如果你修改了代码,需要在被修改的文件中说明;
13 | 3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
14 | 带有原来代码中的协议,商标,专利声明和其他原来作者规
15 | 定需要包含的说明;
16 | 4. 如果再发布的产品中包含一个Notice文件,则在Notice文
17 | 件中需要带有本协议内容。你可以在Notice中增加自己的
18 | 许可,但不可以表现为对Apache Licence构成更改。
19 | 具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 | POSSIBILITY OF SUCH DAMAGE.
33 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please report security issues to `yupoxiong [at] gmail.com`.
--------------------------------------------------------------------------------
/app/.htaccess:
--------------------------------------------------------------------------------
1 | deny from all
--------------------------------------------------------------------------------
/app/AppService.php:
--------------------------------------------------------------------------------
1 | [
10 | // 后台名称
11 | 'name'=>'XX后台系统',
12 | // 后台简称
13 | 'short_name'=>'后台',
14 | // 后台作者
15 | 'author'=>'xx科技',
16 | // 作者网站
17 | 'website'=>'#',
18 | // 后台版本
19 | 'version'=>'0.1',
20 | // 后台LOGO
21 | 'logo'=>'/static/admin/images/logo.png',
22 | ],
23 | // 登录设置:后台登录相关设置
24 | 'login'=>[
25 | // 登录token验证
26 | 'token'=>'0',
27 | // 验证码
28 | 'captcha'=>'1',
29 | // 登录背景
30 | 'background'=>'/static/admin/images/login-default-bg.jpg',
31 | // 极验ID
32 | 'geetest_id'=>'66cfc0f309e368364b753dad7d2f67f2',
33 | // 极验KEY
34 | 'geetest_key'=>'99750f86ec232c997efaff56c7b30cd3',
35 | // 登录重试限制
36 | 'login_limit'=>'1',
37 | // 限制最大次数
38 | 'login_max_count'=>'5',
39 | // 禁止登录时长(小时)
40 | 'login_limit_hour'=>'2',
41 | ],
42 | // 安全设置:安全相关配置
43 | 'safe'=>[
44 | // 加密key
45 | 'admin_key'=>'89ce3272dc949fc3698fe7108d1dbe37',
46 | // SessionKeyUid
47 | 'store_uid_key'=>'admin_user_id',
48 | // SessionKeySign
49 | 'store_sign_key'=>'admin_user_sign',
50 | // 后台用户密码强度检测
51 | 'password_check'=>'0',
52 | // 密码安全强度等级
53 | 'password_level'=>'2',
54 | // 单设备登录
55 | 'one_device_login'=>'1',
56 | // CSRFToken检测
57 | 'check_token'=>'1',
58 | // CSRFToken验证方法
59 | 'check_token_action_list'=>'add,edit,del,import,profile,update',
60 | ],
61 | ];
--------------------------------------------------------------------------------
/app/admin/config/app.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | $config = [
8 |
9 | 'default_ajax_return' => 'html',
10 | ];
11 | if (!env('app_debug')) {
12 | // 自定后台义异常页面的模板文件
13 | $config['exception_tmpl'] = app()->getAppPath() . 'view/error/500.html';
14 | }
15 | return $config;
--------------------------------------------------------------------------------
/app/admin/config/captcha.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | return [
8 | // 验证码字体大小
9 | 'fontSize' => 30,
10 | // 验证码位数
11 | 'length' => 4,
12 | // 关闭验证码杂点
13 | 'useNoise' => false,
14 | // 只用数字
15 | 'codeSet' => '0123456789',
16 | ];
17 |
--------------------------------------------------------------------------------
/app/admin/config/view.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | return [
8 | // 模版替换参数
9 | 'tpl_replace_string' => [
10 | '__STATIC__' => '/static',
11 | '__ADMIN_STATIC__' => '/static/admin',
12 | '__ADMIN_JS__' => '/static/admin/js',
13 | '__ADMIN_CSS__' => '/static/admin/css',
14 | '__ADMIN_IMAGES__' => '/static/admin/images',
15 | '__ADMIN_PLUGINS__' => '/static/admin/plugins',
16 | ]
17 | ];
18 |
--------------------------------------------------------------------------------
/app/admin/controller/ErrorController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\controller;
10 |
11 | use Exception;
12 |
13 | class ErrorController extends AdminBaseController
14 | {
15 | /**
16 | * 403 没有权限访问
17 | * @throws Exception
18 | */
19 | public function err403(): string
20 | {
21 | return $this->fetch('error/403');
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/admin/controller/IndexController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\controller;
10 |
11 | use Exception;
12 |
13 | class IndexController extends AdminBaseController
14 | {
15 | /**
16 | * 后台首页
17 | * @return string
18 | * @throws Exception
19 | */
20 | public function index(): string
21 | {
22 | return $this->fetch();
23 | }
24 | }
--------------------------------------------------------------------------------
/app/admin/event.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | use app\admin\listener\AdminUserLogin;
8 | use app\admin\listener\AdminUserLogout;
9 |
10 | return [
11 | 'bind' => [
12 |
13 | ],
14 |
15 | 'listen' => [
16 | // AdminUserLogin
17 | 'AdminUserLogin' => [
18 | AdminUserLogin::class,
19 | ],
20 | 'AdminUserLogout' => [
21 | AdminUserLogout::class,
22 | ],
23 | 'AppInit' => [],
24 | 'HttpRun' => [],
25 | 'HttpEnd' => [],
26 | 'LogLevel' => [],
27 | 'LogWrite' => [],
28 | ],
29 |
30 | 'subscribe' => [
31 | ],
32 | ];
33 |
--------------------------------------------------------------------------------
/app/admin/exception/AdminServiceException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\exception;
10 |
11 | use Exception;
12 |
13 | class AdminServiceException extends Exception
14 | {
15 | }
--------------------------------------------------------------------------------
/app/admin/listener/AdminUserLogin.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\listener;
10 |
11 | use think\facade\Log;
12 | use app\admin\service\AdminLogService;
13 | use app\admin\exception\AdminServiceException;
14 |
15 | class AdminUserLogin
16 | {
17 |
18 | public function handle($user): void
19 | {
20 | try {
21 | // 记录日志
22 | (new AdminLogService())->create($user, '登录');
23 | } catch (AdminServiceException $e) {
24 | Log::error('记录登录异常,信息:'.$e->getMessage());
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/admin/listener/AdminUserLogout.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\listener;
10 |
11 | use think\facade\Log;
12 | use app\admin\service\AdminLogService;
13 | use app\admin\exception\AdminServiceException;
14 |
15 | class AdminUserLogout
16 | {
17 | public function handle($user): void
18 | {
19 | try {
20 | (new AdminLogService)->create($user, '退出');
21 | } catch (AdminServiceException $e) {
22 | Log::error('记录退出异常,信息:'.$e->getMessage());
23 | }
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/admin/middleware.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\model;
10 |
11 | use app\common\model\CommonBaseModel;
12 |
13 | class AdminBaseModel extends CommonBaseModel
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/app/admin/model/AdminLog.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\model;
10 |
11 | use think\model\relation\HasOne;
12 | use think\model\concern\SoftDelete;
13 | use think\model\relation\BelongsTo;
14 |
15 | /**
16 | * Class AdminLog
17 | * @package app\admin\model
18 | * @property string $log_ip
19 | */
20 | class AdminLog extends AdminBaseModel
21 | {
22 | use SoftDelete;
23 | /**
24 | * @var array 搜索的字段:操作,URL
25 | */
26 | public array $searchField = [
27 | 'name',
28 | 'url',
29 | ];
30 |
31 | public array $whereField = [
32 | 'admin_user_id'
33 | ];
34 |
35 | /**
36 | * 关联用户
37 | * @return BelongsTo
38 | */
39 | public function adminUser(): BelongsTo
40 | {
41 | return $this->belongsTo(AdminUser::class);
42 | }
43 |
44 | /**
45 | * 关联详情
46 | * @return HasOne
47 | */
48 | public function adminLogData(): HasOne
49 | {
50 | return $this->hasOne(AdminLogData::class);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/admin/model/AdminLogData.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\model;
10 |
11 | use JsonException;
12 | use think\model\concern\SoftDelete;
13 | use think\model\relation\BelongsTo;
14 |
15 | class AdminLogData extends AdminBaseModel
16 | {
17 | use SoftDelete;
18 | /**
19 | * 关联log
20 | * @return BelongsTo
21 | */
22 | public function adminLog(): BelongsTo
23 | {
24 | return $this->belongsTo(AdminLog::class);
25 | }
26 |
27 | /**
28 | * @throws JsonException
29 | */
30 | public function getDataFormatAttr($value, $data)
31 | {
32 | return json_encode(json_decode($data['data'], true, 512, JSON_THROW_ON_ERROR), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/admin/model/AdminMenu.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\model;
10 |
11 | use think\model\concern\SoftDelete;
12 |
13 | /**
14 | * Class AdminMenu
15 | * @package app\admin\model
16 | * @property int $parent_id
17 | * @property string $name
18 | * @property int $id
19 | * @property string $icon
20 | * @property string $url
21 | * @property string $log_method
22 | */
23 | class AdminMenu extends AdminBaseModel
24 | {
25 | use SoftDelete;
26 | /**
27 | * @var array 不允许被删除的菜单ID
28 | */
29 | public array $noDeletionIds = [
30 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
31 | ];
32 |
33 | /**
34 | * @var array 日志记录方法列表
35 | */
36 | public static array $logMethodList = [
37 | [
38 | 'id' => '不记录',
39 | 'name' => '不记录',
40 | ],
41 | [
42 | 'id' => 'GET',
43 | 'name' => 'GET',
44 | ],
45 | [
46 | 'id' => 'POST',
47 | 'name' => 'POST',
48 | ],
49 | [
50 | 'id' => 'PUT',
51 | 'name' => 'PUT',
52 | ],
53 | [
54 | 'id' => 'DELETE',
55 | 'name' => 'DELETE',
56 | ],
57 | [
58 | 'id' => 'PATCH',
59 | 'name' => 'PATCH',
60 | ],
61 | ];
62 | }
63 |
--------------------------------------------------------------------------------
/app/admin/model/AdminRole.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace app\admin\model;
8 |
9 | use think\model\concern\SoftDelete;
10 |
11 | /**
12 | * Class AdminRole
13 | * @package app\admin\model
14 | * @property array $url
15 | */
16 | class AdminRole extends AdminBaseModel
17 | {
18 | use SoftDelete;
19 |
20 | public array $searchField = [
21 | 'name'
22 | ];
23 |
24 | /**
25 | * 角色初始权限
26 | * @param AdminRole $data
27 | * @return void
28 | */
29 | public static function onBeforeInsert($data): void
30 | {
31 | $data->url = empty($data->url) ? [1, 2, 18] : $data->url;
32 | }
33 |
34 | protected function getUrlAttr($value)
35 | {
36 | return !empty($value) ? explode(',', $value) : [];
37 | }
38 |
39 | protected function setUrlAttr($value): string
40 | {
41 | return !empty($value) ? implode(',', $value) : '';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/admin/provider.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | return [
8 | 'think\Paginator' => 'app\admin\service\PageService'
9 | ];
--------------------------------------------------------------------------------
/app/admin/service/AdminBaseService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\service;
10 |
11 | class AdminBaseService
12 | {
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/admin/service/AdminLogService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\service;
10 |
11 | use Exception;
12 | use think\facade\Db;
13 | use app\admin\model\AdminLog;
14 | use app\admin\model\AdminUser;
15 | use app\admin\exception\AdminServiceException;
16 |
17 | class AdminLogService extends AdminBaseService
18 | {
19 | protected AdminLog $model;
20 |
21 | public function __construct()
22 | {
23 | $this->model = new AdminLog();
24 | }
25 |
26 | /**
27 | * 创建日志
28 | * @param AdminUser $user 用户
29 | * @param string $name 操作名称
30 | * @throws AdminServiceException
31 | */
32 | public function create(AdminUser $user, string $name): void
33 | {
34 | Db::startTrans();
35 | try {
36 | $data = [
37 | 'admin_user_id' => $user->id,
38 | 'name' => $name,
39 | 'log_method' => request()->method(),
40 | 'url' => request()->url(),
41 | 'log_ip' => request()->ip()
42 | ];
43 | $log = $this->model::create($data);
44 |
45 | $data_arr = [
46 | 'header' => request()->header(),
47 | 'param' => request()->param(),
48 | ];
49 | $log_data = [
50 | 'data' => json_encode($data_arr, JSON_THROW_ON_ERROR),
51 | ];
52 | $log->adminLogData()->save($log_data);
53 |
54 | Db::commit();
55 | } catch (Exception $exception) {
56 | Db::rollback();
57 | throw new AdminServiceException($exception->getMessage());
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/admin/service/AdminRoleService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\service;
10 |
11 | use think\Collection;
12 | use app\admin\model\AdminRole;
13 | use think\db\exception\DbException;
14 | use think\db\exception\DataNotFoundException;
15 | use think\db\exception\ModelNotFoundException;
16 |
17 | class AdminRoleService
18 | {
19 | protected AdminRole $model;
20 |
21 | public function __construct()
22 | {
23 | $this->model = new AdminRole();
24 | }
25 |
26 | /**
27 | * 获取所有角色
28 | * @return AdminRole[]|array|Collection
29 | */
30 | public function getAll()
31 | {
32 | try {
33 | return $this->model->select();
34 | } catch (DataNotFoundException | ModelNotFoundException | DbException $e) {
35 | return [];
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/admin/validate/AdminBaseValidate.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\validate;
10 |
11 | use app\common\validate\CommonBaseValidate;
12 |
13 | class AdminBaseValidate extends CommonBaseValidate
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/app/admin/validate/AdminMenuValidate.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\validate;
10 |
11 | class AdminMenuValidate extends AdminBaseValidate
12 | {
13 | protected $rule = [
14 | 'parent_id|父级菜单' => 'require|egt:0',
15 | 'name|名称' => 'require',
16 | 'url|URL' => 'require|unique:admin_menu',
17 | 'icon|图标' => 'require',
18 | 'sort_number|排序' => 'require',
19 | 'is_show|是否显示' => 'require',
20 | 'log_method|日志记录方式' => 'require',
21 | ];
22 |
23 | protected $message = [
24 | 'parent_id.egt' => '请选择上级菜单',
25 | ];
26 |
27 | protected $scene = [
28 | 'admin_add' => ['parent_id', 'title', 'url', 'icon', 'sort_number', 'is_show', 'log_method'],
29 | 'admin_edit' => ['parent_id', 'title', 'url', 'icon', 'sort_number', 'is_show', 'log_method'],
30 | ];
31 |
32 | }
--------------------------------------------------------------------------------
/app/admin/validate/AdminRoleValidate.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\validate;
10 |
11 | class AdminRoleValidate extends AdminBaseValidate
12 | {
13 | protected $rule = [
14 | 'name|名称' => 'require',
15 | 'description|介绍' => 'require',
16 | 'rules|权限' => 'require',
17 | ];
18 |
19 | protected $scene = [
20 | 'admin_add' => ['name', 'description'],
21 | 'admin_edit' => ['name', 'description'],
22 | ];
23 | }
24 |
--------------------------------------------------------------------------------
/app/admin/validate/AdminUserValidate.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\admin\validate;
10 |
11 | class AdminUserValidate extends AdminBaseValidate
12 | {
13 | protected $rule = [
14 | 'username|帐号' => 'require|unique:admin_user',
15 | 'password|密码' => 'require',
16 | 'current_password|当前密码' => 'require',
17 | 'new_password|新密码' => 'require',
18 | 're_new_password|确认新密码' => 'require|confirm:new_password',
19 | 'nickname|昵称' => 'require',
20 | 'role|角色' => 'require',
21 | 'status|状态' => 'require',
22 | ];
23 |
24 | protected $message = [
25 | 'name.require' => '名称必须',
26 | 'name.max' => '名称最多不能超过25个字符',
27 | 'age.number' => '年龄必须是数字',
28 | 'age.between' => '年龄只能在1-120之间',
29 | 'email' => '邮箱格式错误',
30 | ];
31 |
32 | protected $scene = [
33 | 'admin_add' => ['username', 'password'],
34 | 'admin_edit' => ['username', 'password'],
35 | 'admin_login' => ['username', 'password'],
36 | 'admin_password' => ['current_password', 'new_password', 're_new_password'],
37 | ];
38 |
39 | public function sceneLogin(): void
40 | {
41 | $this->only(['username', 'password'])
42 | ->remove('username', 'unique');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/admin/view/auth/captcha.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
26 |
27 |
--------------------------------------------------------------------------------
/app/admin/view/auth/login_bg.html:
--------------------------------------------------------------------------------
1 |
2 | {if $login_config.background}
3 |
13 | {/if}
--------------------------------------------------------------------------------
/app/admin/view/database/view.html:
--------------------------------------------------------------------------------
1 |
2 | {extend name='public/layer_base' /}
3 | {block name='content'}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 字段名
13 | 类型
14 | 排序规则
15 | 是否为空
16 | 是否为主键
17 | 默认值
18 | 更多信息
19 | 备注
20 |
21 |
22 |
23 | {foreach name='data' id='item'}
24 |
25 | {$item.name}
26 | {$item.type}
27 | {$item.collation}
28 | {$item.null}
29 | {$item.key}
30 | {$item.default}
31 | {$item.extra}
32 | {$item.comment}
33 |
34 | {/foreach}
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/error/403.html:
--------------------------------------------------------------------------------
1 | {extend name='public/base' /}
2 | {block name='content'}
3 | {include file='public/content_header' /}
4 |
5 |
6 |
403
7 |
8 |
抱歉! 没有权限。
9 |
10 | 您访问的页面没有权限,您可以 点此去首页
11 |
12 |
13 |
14 |
15 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/error/404.html:
--------------------------------------------------------------------------------
1 | {extend name='public/base' /}
2 | {block name='content'}
3 | {include file='public/content_header' /}
4 |
5 |
6 |
404
7 |
8 |
糟糕! 页面未找到。
9 |
10 | 您访问的页面不存在,您可以 点此去首页
11 |
12 |
13 |
14 |
15 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/file/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/admin/view/generate/index.html:
--------------------------------------------------------------------------------
1 | {extend name="public/base" /}
2 | {block name='content'}
3 | {include file='public/content_header' /}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
代码自动生成
11 |
点击跳转
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
表单字段生成
21 |
点击跳转
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/index/index.html:
--------------------------------------------------------------------------------
1 |
2 | {extend name='public/base' /}
3 | {block name='content'}
4 | {include file='public/content_header' /}
5 |
6 |
7 |
8 |
9 | {include file='index/top_widget1' /}
10 |
11 | {include file='index/top_widget2' /}
12 |
13 | {include file='index/chart1' /}
14 |
15 | {include file='index/chart2' /}
16 |
17 | {include file='index/chart3' /}
18 |
19 |
20 |
21 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/index/top_widget2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 消息数
9 | 1,410
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 书签数
20 | 410
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 附件数
31 | 13,648
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | 收藏数
43 | 93,139
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/admin/view/public/base.html:
--------------------------------------------------------------------------------
1 | {if !$admin.is_pjax}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {/if}
12 |
13 | {block name='title'}
14 | {$admin.title|default='Admin'} | {$admin.base.name|default='Admin'}
15 | {/block}
16 |
17 | {if !$admin.is_pjax}
18 |
19 | {include file='public/head_css' /}
20 | {include file='public/head_js' /}
21 |
22 |
23 |
24 | {/if}
25 |
26 |
27 | {block name='navbar'}
28 | {include file='public/navbar/navbar' /}
29 | {/block}
30 |
31 |
32 | {block name='sidebar'}
33 | {include file='public/sidebar' /}
34 | {/block}
35 |
36 |
37 |
38 | {block name='content'}
39 | {/block}
40 |
41 |
42 |
43 | {block name='footer'}
44 | {include file='public/footer' /}
45 | {/block}
46 |
47 |
48 | {block name='control_sidebar'}
49 | {include file='public/control_sidebar' /}
50 | {/block}
51 |
52 | {if !$admin.is_pjax}
53 |
54 | {/if}
55 |
56 | {if !$admin.is_pjax}
57 |
58 |
59 |
60 | {/if}
--------------------------------------------------------------------------------
/app/admin/view/public/change_page.html:
--------------------------------------------------------------------------------
1 |
2 | 共{$total}条记录
3 | 每页显示
4 |
5 |
6 | 10
7 | 20
8 | 30
9 | 50
10 | 100
11 |
12 |
13 | 条记录
14 |
--------------------------------------------------------------------------------
/app/admin/view/public/content_header.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/admin/view/public/footer.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/admin/view/public/head_css.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {css href="__ADMIN_PLUGINS__/viewer/viewer.min.css" /}
4 | {css href="__ADMIN_PLUGINS__/nprogress/nprogress.css" /}
5 | {css href="__ADMIN_PLUGINS__/select2/css/select2.min.css" /}
6 | {css href="__ADMIN_PLUGINS__/fileinput/css/fileinput.min.css" /}
7 | {css href="__ADMIN_PLUGINS__/fontawesome-free/css/all.min.css" /}
8 | {css href="__ADMIN_PLUGINS__/icheck-bootstrap/icheck-bootstrap.min.css" /}
9 | {css href="__ADMIN_PLUGINS__/select2-bootstrap4-theme/select2-bootstrap4.min.css" /}
10 | {css href="__ADMIN_PLUGINS__/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css" /}
11 | {css href="__ADMIN_PLUGINS__/bootstrap-switch/css/bootstrap3/bootstrap-switch.min.css" /}
12 | {css href="__ADMIN_PLUGINS__/fontawesome-iconpicker/css/fontawesome-iconpicker.min.css" /}
13 | {css href="__ADMIN_CSS__/adminlte.min.css" /}
14 | {css href="__ADMIN_CSS__/admin.css" /}
15 |
--------------------------------------------------------------------------------
/app/admin/view/public/layer_base.html:
--------------------------------------------------------------------------------
1 | {if !$admin.is_pjax}
2 | {include file='public/head_css' /}
3 | {include file='public/head_js' /}
4 | {/if}
5 |
6 |
7 | {block name='content'}
8 | {/block}
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/nav.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {if $admin.top_nav===1 && isset($admin.top_menu)}
10 | {foreach $admin.top_menu as $key=>$nav}
11 |
12 |
13 | {$nav.name}
14 |
15 | {/foreach}
16 | {/if}
17 |
18 |
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/navbar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {include file='public/navbar/nav' /}
7 |
8 |
9 | {include file='public/navbar/search_form' /}
10 |
11 |
12 |
13 |
14 | {include file='public/navbar/message' /}
15 |
16 |
17 | {include file='public/navbar/notification' /}
18 |
19 |
20 | {include file='public/navbar/user_menu' /}
21 |
22 |
23 | {include file='public/navbar/sidebar_button' /}
24 |
25 |
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/notification.html:
--------------------------------------------------------------------------------
1 | {if $admin.top_notification}
2 |
3 |
4 |
5 |
6 | 15
7 |
8 |
28 |
29 | {/if}
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/search_form.html:
--------------------------------------------------------------------------------
1 | {if $admin.top_search}
2 |
12 | {/if}
13 |
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/sidebar_button.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/admin/view/public/navbar/user_menu.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/admin/view/public/sidebar.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/admin/view/template/content.html:
--------------------------------------------------------------------------------
1 |
2 | {extend name='public/base' /}
3 | {block name='content'}
4 | {include file='public/content_header' /}
5 |
10 |
11 | {/block}
--------------------------------------------------------------------------------
/app/admin/view/template/layer_content.html:
--------------------------------------------------------------------------------
1 |
2 | {extend name='public/layer_base' /}
3 | {block name='content'}
4 |
9 |
10 | {/block}
--------------------------------------------------------------------------------
/app/api/config/api.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | return [
8 |
9 | // api跨域设置
10 | 'cross_domain' => [
11 | // 是否允许跨域
12 | 'allow' => env('api.allow_cross_domain', true),
13 | // header设置
14 | 'header' => [
15 | 'Access-Control-Allow-Origin' => '*',
16 | 'Access-Control-Allow-Methods' => '*',
17 | 'Access-Control-Allow-Headers' => 'Content-Type,' . (env('api.token_position') === 'header' ? env('api.token_field') : 'token'),
18 | 'Access-Control-Request-Headers' => 'Origin, Content-Type, Accept, ' . (env('api.token_position') === 'header' ? env('api.token_field') : 'token'),
19 | ],
20 | ],
21 | // api响应配置
22 | 'response' => [
23 | // HTTP状态码和业务状态码同步
24 | 'http_code_sync' => env('api.http_code_sync', false),
25 | ],
26 | 'auth' => [
27 | 'jwt_key' => env('api.jwt_key', 'f2244f5316b70ef2887514b65caf795f'),
28 | 'jwt_exp' => (int)env('api.jwt_exp', 3600),
29 | 'jwt_aud' => env('api.jwt_aud', 'a'),
30 | 'jwt_iss' => env('api.jwt_iss', 's'),
31 | 'enable_refresh_token' => (bool)env('api.enable_refresh_token', true),
32 | 'refresh_token_exp' => (int)env('api.refresh_token_exp', 1296000),
33 | 'reuse_check' => (bool)env('api.reuse_check', true),
34 | 'token_position' => env('api.token_position', 'header'),
35 | 'token_field' => env('api.token_field', 'token'),
36 | ]
37 |
38 | ];
39 |
--------------------------------------------------------------------------------
/app/api/controller/AuthController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\api\controller;
10 |
11 | use app\common\validate\UserValidate;
12 | use think\Request;
13 | use think\response\Json;
14 | use app\api\service\AuthService;
15 | use app\api\exception\ApiServiceException;
16 |
17 | class AuthController
18 | {
19 | /**
20 | * @param Request $request
21 | * @param UserValidate $validate
22 | * @param AuthService $service
23 | * @return Json
24 | */
25 | public function login(Request $request, UserValidate $validate,AuthService $service): Json
26 | {
27 | $param = $request->param();
28 |
29 | $check = $validate->scene('api_login')->check($param);
30 | if (!$check) {
31 | return api_error($validate->getError());
32 | }
33 |
34 | try {
35 |
36 | $username = $param['username'];
37 | $password = $param['password'];
38 | $result = $service->usernameLogin($username, $password);
39 |
40 | return api_success($result);
41 | } catch (ApiServiceException $e) {
42 | return api_error('登录失败,参考信息:'.$e->getMessage());
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/app/api/controller/IndexController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\api\controller;
10 |
11 | use think\response\Json;
12 |
13 | class IndexController extends ApiBaseController
14 | {
15 | public function index(): Json
16 | {
17 | return api_success();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/api/controller/TokenController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\api\controller;
11 |
12 |
13 | use app\api\exception\ApiServiceException;
14 | use app\api\service\TokenService;
15 | use think\response\Json;
16 |
17 | class TokenController
18 | {
19 |
20 | /**
21 | * 刷新token,当刷新返回错误的时候需要重新登录
22 | * @return Json
23 | */
24 | public function refresh(): Json
25 | {
26 | $param = request()->param();
27 | $refresh_token = $param['refresh_token'];
28 | $service = new TokenService();
29 |
30 | try {
31 | $data = $service->refreshToken($refresh_token);
32 | return api_success($data);
33 | } catch (ApiServiceException $e) {
34 | return api_error($e->getMessage());
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/app/api/exception/ApiServiceException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\api\exception;
10 |
11 | use Exception;
12 |
13 | class ApiServiceException extends Exception
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/app/api/middleware.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | $config = [];
8 | if(env('api.allow_cross_domain')){
9 | $config = [
10 | \app\api\middleware\AllowCrossDomain::class
11 | ];
12 | }
13 |
14 | return $config;
--------------------------------------------------------------------------------
/app/api/middleware/AllowCrossDomain.php:
--------------------------------------------------------------------------------
1 | $value) {
23 | header($key . ':' . $value);
24 | }
25 | if ($request->isOptions()) {
26 | return json('');
27 | }
28 | return $next($request);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/api/service/ApiBaseService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\api\service;
10 |
11 | class ApiBaseService
12 | {
13 |
14 | }
--------------------------------------------------------------------------------
/app/api/service/AuthService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\api\service;
10 |
11 | use app\api\exception\ApiServiceException;
12 | use app\common\model\User;
13 | use think\facade\Event;
14 |
15 | class AuthService extends ApiBaseService
16 | {
17 | protected User $model;
18 |
19 | public function __construct()
20 | {
21 | $this->model = new User();
22 | }
23 |
24 | /**
25 | * @param $username
26 | * @param $password
27 | * @return array
28 | * @throws ApiServiceException
29 | */
30 | public function usernameLogin($username, $password): array
31 | {
32 | /** @var User $user */
33 | $user = $this->model->where('username', '=', $username)->findOrEmpty();
34 |
35 | if ($user->isEmpty()) {
36 | throw new ApiServiceException('用户不存在');
37 | }
38 |
39 | $verify = password_verify($password, base64_decode($user->password));
40 | if (!$verify) {
41 | throw new ApiServiceException('密码错误');
42 | }
43 |
44 | // 检查是否被冻结
45 | if ($user->status !== 1) {
46 | throw new ApiServiceException('账号被冻结');
47 | }
48 |
49 | // Event_事件 管理用户登录
50 | Event::trigger('UserLogin', $user);
51 |
52 | $service = new TokenService();
53 |
54 | $data = [
55 | 'access_token' => $service->getAccessToken($user->id),
56 | ];
57 | if ($service->isEnableRefreshToken()) {
58 | $data['refresh_token'] = $service->getRefreshToken($user->id);
59 | }
60 |
61 | return $data;
62 | }
63 |
64 | }
--------------------------------------------------------------------------------
/app/command/GenerateAppKey.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | declare (strict_types=1);
7 |
8 | namespace app\command;
9 |
10 | use think\console\Command;
11 | use think\console\Output;
12 | use think\console\Input;
13 |
14 | class GenerateAppKey extends Command
15 | {
16 | protected function configure()
17 | {
18 | // 指令配置
19 | $this->setName('generate:app_key')
20 | ->setDescription('生成新的APP_KEY');
21 | }
22 |
23 | protected function execute(Input $input, Output $output)
24 | {
25 | $env = app()->getRootPath() . '.env';
26 | $search = 'APP_KEY=' . env('app.app_key');
27 | $key = md5(uniqid('app_key', true));
28 | $result = file_put_contents($env, str_replace($search, 'APP_KEY=' . $key, file_get_contents($env)));
29 | if ($result) {
30 | $output->writeln('新的APP_KEY生成成功,值为:' . $key);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/command/GenerateJwtKey.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | declare (strict_types=1);
7 |
8 | namespace app\command;
9 |
10 | use think\console\Command;
11 | use think\console\Output;
12 | use think\console\Input;
13 |
14 | class GenerateJwtKey extends Command
15 | {
16 | protected function configure()
17 | {
18 | // 指令配置
19 | $this->setName('generate:jwt_key')
20 | ->setDescription('生成新的JWT_KEY');
21 | }
22 |
23 | protected function execute(Input $input, Output $output)
24 | {
25 | $env = app()->getRootPath() . '.env';
26 | $search = 'JWT_KEY=' . env('api.jwt_key');
27 | $key = md5(uniqid('jwt_key', true));
28 | $result = file_put_contents($env, str_replace($search, 'JWT_KEY=' . $key, file_get_contents($env)));
29 | if ($result) {
30 | $output->writeln('新的JWT_KEY生成成功,值为:' . $key);
31 | }
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/app/command/InitEnv.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\command;
10 |
11 | use think\console\input\Option;
12 | use think\console\Command;
13 | use think\facade\Console;
14 | use think\console\Output;
15 | use think\console\Input;
16 |
17 | class InitEnv extends Command
18 | {
19 | protected function configure()
20 | {
21 | $this->setName('init:env')
22 | ->addOption('--force', '-f', Option::VALUE_NONE, '强制初始化env配置文件')
23 | ->setDescription('初始化项目env配置文件');
24 | }
25 |
26 | protected function execute(Input $input, Output $output)
27 | {
28 | $force = $input->getOption('force');
29 |
30 | $example_file = $this->app->getRootPath() . '.example.env';
31 | $env_file = $this->app->getRootPath() . '.env';
32 |
33 | if ($force === true || !file_exists($env_file)) {
34 | copy($example_file, $env_file);
35 | $output->info('env配置文件初始化成功');
36 |
37 | $app_key_result = Console::call('generate:app_key');
38 | $output->info($app_key_result->fetch());
39 | $jwt_key_result = Console::call('generate:jwt_key');
40 | $output->info($jwt_key_result->fetch());
41 | } else {
42 | $output->info('env配置文件已存在');
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/command/ResetAdminPassword.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\command;
10 |
11 | use app\common\exception\CommonServiceException;
12 | use app\common\service\StringService;
13 | use think\console\input\Argument;
14 | use think\console\input\Option;
15 | use app\admin\model\AdminUser;
16 | use think\console\Command;
17 | use think\console\Output;
18 | use think\console\Input;
19 |
20 | class ResetAdminPassword extends Command
21 | {
22 | protected function configure()
23 | {
24 | $this->setName('reset:admin_password')
25 | ->addArgument('password', Argument::OPTIONAL, "新密码,可空")
26 | ->addOption('uid', null, Option::VALUE_REQUIRED, '需要重置密码的用户ID')
27 | ->setDescription('重置后台用户密码,默认重置开发管理员密码');
28 | }
29 |
30 | /**
31 | * @throws CommonServiceException
32 | */
33 | protected function execute(Input $input, Output $output)
34 | {
35 | $password = trim((string)$input->getArgument('password'));
36 | $password = $password ?: StringService::getRandString(10, true, true, true, false);
37 |
38 | $uid = 1;
39 | if ($input->hasOption('uid')) {
40 | $uid = $input->getOption('uid');
41 | }
42 |
43 | $user = (new AdminUser())->where('id', '=', $uid)->findOrEmpty();
44 | if ($user->isEmpty()) {
45 | $output->error('用户不存在');
46 | return;
47 | }
48 |
49 | $user->password = $password;
50 | $result = $user->save();
51 | $output_text = '[ID:' . $user->id . ']' . $user->nickname;
52 | if ($result) {
53 | $output->info($output_text . '的密码重置成功,新密码为:' . $password);
54 | return;
55 | }
56 |
57 | $output->error($output_text . '的密码重置失败');
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/command/Test.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\command;
10 |
11 | use think\console\Command;
12 | use think\console\Input;
13 | use think\console\Output;
14 |
15 | class Test extends Command
16 | {
17 |
18 | protected function configure()
19 | {
20 | $this->setName('test')
21 | ->setDescription('测试命令');
22 | }
23 |
24 | protected function execute(Input $input, Output $output)
25 | {
26 | $output->info('这是测试信息');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/common/exception/CommonServiceException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\common\exception;
11 |
12 |
13 | use Exception;
14 |
15 | class CommonServiceException extends Exception
16 | {
17 |
18 | }
--------------------------------------------------------------------------------
/app/common/model/Setting.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace app\common\model;
8 |
9 | use JsonException;
10 | use think\model\concern\SoftDelete;
11 | use think\model\relation\BelongsTo;
12 |
13 | /**
14 | * Class Setting
15 | * @package app\common\model
16 | * @property int $id ID
17 | * @property int $name 名称
18 | * @property string $code 代码
19 | * @property array $content 设置内容
20 | * @property int $setting_group_id 所属分组ID
21 | */
22 | class Setting extends CommonBaseModel
23 | {
24 | use SoftDelete;
25 |
26 | protected $name = 'setting';
27 | protected $autoWriteTimestamp = true;
28 |
29 | public array $noDeletionIds = [
30 | 1, 2, 3, 4, 5,
31 | ];
32 |
33 | //可搜索字段
34 | public array $searchField = ['name', 'description', 'code',];
35 |
36 |
37 | //关联设置分组
38 | public function settingGroup(): BelongsTo
39 | {
40 | return $this->belongsTo(SettingGroup::class);
41 | }
42 |
43 |
44 | public function setContentAttr($value)
45 | {
46 | try {
47 | return json_encode($value, JSON_THROW_ON_ERROR);
48 | } catch (JsonException $e) {
49 | return (object)[];
50 | }
51 | }
52 |
53 | public function getContentAttr($value)
54 | {
55 | try {
56 | return json_decode($value, true, 512, JSON_THROW_ON_ERROR);
57 | } catch (JsonException $e) {
58 | return [];
59 | }
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/app/common/model/SettingGroup.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace app\common\model;
8 |
9 | use think\model\Collection;
10 | use think\model\relation\HasMany;
11 | use think\model\concern\SoftDelete;
12 |
13 | /**
14 | * Class SettingGroup
15 | * @package app\common\model
16 | * @property int $id
17 | * @property string $name
18 | * @property int $auto_create_file
19 | * @property int $auto_create_menu
20 | * @property string $code
21 | * @property string $module
22 | * @property string $description
23 | * @property Setting[] $setting
24 | * @property string $icon
25 | */
26 | class SettingGroup extends CommonBaseModel
27 | {
28 | use SoftDelete;
29 | protected $name = 'setting_group';
30 | protected $autoWriteTimestamp = true;
31 |
32 | public array $noDeletionIds =[
33 | 1,2,3,4,5,
34 | ];
35 |
36 | // 可搜索字段
37 | public array $searchField = ['name', 'description', 'code',];
38 |
39 | // 关联设置
40 | public function setting(): HasMany
41 | {
42 | return $this->hasMany(Setting::class);
43 | }
44 |
45 | /**
46 | * 自动生成菜单字段获取器
47 | * @param $value
48 | * @param $data
49 | * @return string
50 | */
51 | public function getAutoCreateMenuTextAttr($value,$data): string
52 | {
53 | return self::BOOLEAN_TEXT[$data['auto_create_menu']];
54 | }
55 |
56 | /**
57 | * 自动生成配置文件获取器
58 | * @param $value
59 | * @param $data
60 | * @return string
61 | */
62 | public function getAutoCreateFileTextAttr($value,$data): string
63 | {
64 | return self::BOOLEAN_TEXT[$data['auto_create_file']];
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/common/model/Test.php:
--------------------------------------------------------------------------------
1 | belongsTo(UserLevel::class);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/common/model/UserLevel.php:
--------------------------------------------------------------------------------
1 | hasMany(Test::class);
34 | }// 关联用户
35 | public function user(): HasMany
36 | {
37 | return $this->hasMany(User::class);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/common/service/CommonBaseService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\common\service;
11 |
12 |
13 | class CommonBaseService
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/app/common/service/DateService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\common\service;
10 |
11 | class DateService
12 | {
13 | /**
14 | * 获取当前微秒时间戳
15 | * @return string
16 | */
17 | public static function microTimestamp(): string
18 | {
19 | $time = explode(' ', microtime());
20 | $micro = substr($time[0], 2, 3);
21 | return $time[1] . $micro;
22 | }
23 |
24 | /**
25 | * 获取指定日期当月第一天
26 | * @param $date
27 | * @return false|string
28 | */
29 | public static function getCurMonthFirstDay($date) {
30 | return date('Y-m-01', strtotime($date));
31 | }
32 |
33 | /**
34 | * 获取指定日期当月最后一天
35 | * @param $date
36 | * @return false|string
37 | */
38 | public static function getCurMonthLastDay($date) {
39 | return date('Y-m-d', strtotime(date('Y-m-01', strtotime($date)) . ' +1 month -1 day'));
40 | }
41 |
42 | /**
43 | * 获取月初的时间戳
44 | * @param string $month 月份,格式2020-10
45 | * @return false|int
46 | */
47 | public static function getMonthStartTimestamp(string $month)
48 | {
49 | return strtotime($month);
50 | }
51 |
52 | /**
53 | * 获取月末时间戳
54 | * @param string $month 月份,格式2020-10
55 | * @return false|int
56 | */
57 | public static function getMonthEndTimestamp(string $month)
58 | {
59 | return strtotime(date('Y-m-t',strtotime($month)).' 23:59:59');
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/app/common/validate/SettingGroupValidate.php:
--------------------------------------------------------------------------------
1 | 'require|chsDash',
12 | 'description|描述' => 'require|chsDash',
13 | 'module|作用模块' => 'require|alpha|length:1,30',
14 | 'code|代码' => 'require|unique:setting_group|code',
15 | 'sort_number|排序' => 'require|number|elt:9999999999|egt:1',
16 | 'auto_create_menu|自动生成菜单' => 'require',
17 | 'auto_create_file|自动生成配置文件' => 'require',
18 |
19 | ];
20 |
21 | protected $message = [
22 | 'name.require' => '名称不能为空',
23 | 'description.require' => '描述不能为空',
24 | 'module.require' => '作用模块不能为空',
25 | 'code.require' => '代码不能为空',
26 | 'sort_number.require' => '排序不能为空',
27 | 'auto_create_menu.require' => '自动生成菜单不能为空',
28 | 'auto_create_file.require' => '自动生成配置文件不能为空',
29 | ];
30 |
31 | protected $scene = [
32 | 'add' => ['name', 'description', 'module', 'code', 'sort_number', 'auto_create_menu', 'auto_create_file',],
33 | 'edit' => ['name', 'description', 'module', 'code', 'sort_number', 'auto_create_menu', 'auto_create_file',],
34 | ];
35 |
36 |
37 | /**
38 | * 验证code
39 | * @param $value
40 | * @param $rule
41 | * @param array $data
42 | * @param string $field
43 | * @param string $desc
44 | * @return bool|string
45 | */
46 | protected function code($value, $rule, array $data = [], string $field = '', string $desc = '')
47 | {
48 | $pattern = '/^[a-zA-z]\w{2,29}$/';
49 | return preg_match($pattern, $value) ? true : $desc . '的规则为[字母、数字、下划线组成,字母开头,3-30位]';
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/common/validate/SettingValidate.php:
--------------------------------------------------------------------------------
1 | 'require|number|elt:9999|egt:1',
12 | 'name|名称' => 'require|chsDash',
13 | 'description|描述' => 'require|chsDash',
14 | 'code|代码' => 'require|unique:setting|code',
15 | 'sort_number|排序' => 'require|number|elt:9999999999|egt:1',
16 |
17 | ];
18 |
19 | protected $message = [
20 | 'setting_group_id.require' => '所属分组不能为空',
21 | 'name.require' => '名称不能为空',
22 | 'description.require' => '描述不能为空',
23 | 'code.require' => '代码不能为空',
24 | 'sort_number.require' => '排序不能为空',
25 | ];
26 |
27 | protected $scene = [
28 | 'add' => ['setting_group_id', 'name', 'description', 'code', 'sort_number',],
29 | 'edit' => ['setting_group_id', 'name', 'description', 'code', 'sort_number',],
30 | ];
31 |
32 | /**
33 | * 验证code
34 | * @param $value
35 | * @param $rule
36 | * @param array $data
37 | * @param string $field
38 | * @param string $desc
39 | * @return bool|string
40 | */
41 | protected function code($value, $rule, array $data = [], string $field = '', string $desc = '')
42 | {
43 | $pattern = '/^[a-zA-z]\w{2,29}$/';
44 | return preg_match($pattern, $value) ? true : $desc . '的值只能是字母、数字、下划线组成,字母开头,3-50位';
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/common/validate/TestValidate.php:
--------------------------------------------------------------------------------
1 | 'require',
12 | 'username|用户名' => 'require',
13 | 'nickname|昵称' => 'require',
14 | 'mobile|手机号' => 'require',
15 | 'user_level_id|用户等级' => 'require',
16 | 'password|密码' => 'require',
17 | 'status|是否启用' => 'require',
18 | 'slide|相册' => 'require',
19 | 'content|内容' => 'require',
20 |
21 | ];
22 |
23 | protected $message = [
24 | 'avatar.required' => '头像不能为空',
25 | 'username.required' => '用户名不能为空',
26 | 'nickname.required' => '昵称不能为空',
27 | 'mobile.required' => '手机号不能为空',
28 | 'user_level_id.required' => '用户等级不能为空',
29 | 'password.required' => '密码不能为空',
30 | 'status.required' => '是否启用不能为空',
31 | 'slide.required' => '相册不能为空',
32 | 'content.required' => '内容不能为空',
33 |
34 | ];
35 |
36 | protected $scene = [
37 | 'admin_add' => ['avatar', 'username', 'nickname', 'mobile', 'user_level_id', 'password', 'status', 'lng', 'slide', 'content', ],
38 | 'admin_edit' => ['id', 'avatar', 'username', 'nickname', 'mobile', 'user_level_id', 'password', 'status', 'lng', 'slide', 'content', ],
39 | 'admin_del' => ['id', ],
40 | 'admin_disable' => ['id', ],
41 | 'admin_enable' => ['id', ],
42 | 'api_add' => ['avatar', 'username', 'nickname', 'mobile', 'user_level_id', 'password', 'status', 'lng', 'slide', 'content', ],
43 | 'api_info' => ['id', ],
44 | 'api_edit' => ['id', 'avatar', 'username', 'nickname', 'mobile', 'user_level_id', 'password', 'status', 'lng', 'slide', 'content', ],
45 | 'api_del' => ['id', ],
46 | 'api_disable' => ['id', ],
47 | 'api_enable' => ['id', ],
48 | ];
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/app/common/validate/UserLevelValidate.php:
--------------------------------------------------------------------------------
1 | 'require',
12 | 'description|简介' => 'require',
13 | 'img|图片' => 'require',
14 | 'status|是否启用' => 'require',
15 |
16 | ];
17 |
18 | protected $message = [
19 | 'name.required' => '名称不能为空',
20 | 'description.required' => '简介不能为空',
21 | 'img.required' => '图片不能为空',
22 | 'status.required' => '是否启用不能为空',
23 |
24 | ];
25 |
26 | protected $scene = [
27 | 'admin_add' => ['name', 'description', 'img', 'status',],
28 | 'admin_edit' => ['id', 'name', 'description', 'img', 'status',],
29 | 'admin_del' => ['id',],
30 | 'admin_disable' => ['id',],
31 | 'admin_enable' => ['id',],
32 | 'api_add' => ['name', 'description', 'img', 'status',],
33 | 'api_info' => ['id',],
34 | 'api_edit' => ['id', 'name', 'description', 'img', 'status',],
35 | 'api_del' => ['id',],
36 | 'api_disable' => ['id',],
37 | 'api_enable' => ['id',],
38 | ];
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/common/validate/UserValidate.php:
--------------------------------------------------------------------------------
1 | 'require',
12 | 'username|账号' => 'require',
13 | 'password|密码' => 'require',
14 | 'mobile|手机号' => 'require',
15 | 'nickname|昵称' => 'require',
16 | 'avatar|头像' => 'require',
17 | 'status|是否启用' => 'require',
18 |
19 | ];
20 |
21 | protected $message = [
22 | 'user_level_id.required' => '用户等级不能为空',
23 | 'username.required' => '账号不能为空',
24 | 'password.required' => '密码不能为空',
25 | 'mobile.required' => '手机号不能为空',
26 | 'nickname.required' => '昵称不能为空',
27 | 'avatar.required' => '头像不能为空',
28 | 'status.required' => '是否启用不能为空',
29 |
30 | ];
31 |
32 | protected $scene = [
33 | 'admin_add' => ['user_level_id', 'username', 'password', 'mobile', 'nickname', 'avatar', 'status',],
34 | 'admin_edit' => ['id', 'user_level_id', 'username', 'password', 'mobile', 'nickname', 'avatar', 'status',],
35 | 'admin_del' => ['id',],
36 | 'admin_disable' => ['id',],
37 | 'admin_enable' => ['id',],
38 | 'api_add' => ['user_level_id', 'username', 'password', 'mobile', 'nickname', 'avatar', 'status',],
39 | 'api_info' => ['id',],
40 | 'api_edit' => ['id', 'user_level_id', 'username', 'password', 'mobile', 'nickname', 'avatar', 'status',],
41 | 'api_del' => ['id',],
42 | 'api_disable' => ['id',],
43 | 'api_enable' => ['id',],
44 | 'api_login' => ['username', 'password'],
45 | 'index_login' => ['username', 'password'],
46 | ];
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/app/event.php:
--------------------------------------------------------------------------------
1 | [
5 | ],
6 |
7 | 'listen' => [
8 | 'AppInit' => [],
9 | 'HttpRun' => [],
10 | 'HttpEnd' => [],
11 | 'LogLevel' => [],
12 | 'LogWrite' => [],
13 | ],
14 |
15 | 'subscribe' => [
16 | ],
17 | ];
18 |
--------------------------------------------------------------------------------
/app/index/common.php:
--------------------------------------------------------------------------------
1 | build();
28 | if (request()->isPost() || request()->isAjax()) {
29 | $result = [
30 | 'code' => $code,
31 | 'msg' => $msg,
32 | 'data' => $data,
33 | 'url' => $url,
34 | 'wait' => $wait,
35 | ];
36 | return Response::create($result, 'json')->header($header);
37 | }
38 |
39 | if ($url === null) {
40 | $url = request()->server('HTTP_REFERER') ?? url('index/index/index')->build();;
41 | }
42 |
43 | return redirect($url);
44 | }
45 | }
--------------------------------------------------------------------------------
/app/index/config/view.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | return [
8 | // 模版替换参数
9 | 'tpl_replace_string' => [
10 | '__STATIC__' => '/static',
11 | '__INDEX_STATIC__' => '/static/index',
12 | '__INDEX_JS__' => '/static/index/js',
13 | '__INDEX_CSS__' => '/static/index/css',
14 | '__INDEX_IMAGES__' => '/static/index/images',
15 | '__INDEX_PLUGINS__' => '/static/index/plugins',
16 | ]
17 | ];
18 |
--------------------------------------------------------------------------------
/app/index/controller/AuthController.php:
--------------------------------------------------------------------------------
1 | param();
28 |
29 | //登录逻辑
30 | if($request->isPost()){
31 |
32 | $check = $validate->scene('index_login')->check($param);
33 | if (!$check) {
34 | return index_error($validate->getError());
35 | }
36 | try {
37 | $user = $service->login($param['username'], $param['password']);
38 | self::authLogin($user,(bool)($param['remember']??false));
39 | return index_success('登录成功','index/index',$user);
40 | } catch (IndexServiceException $e) {
41 | return index_error($e->getMessage());
42 | }
43 | }
44 |
45 | return $this->fetch();
46 | }
47 |
48 |
49 | /**
50 | * 退出
51 | * @return Redirect
52 | */
53 | public function logout(): Redirect
54 | {
55 | self::authLogout();
56 |
57 | return redirect(url('index/auth/login'));
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/index/controller/IndexController.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace app\index\controller;
10 |
11 | use Exception;
12 |
13 | class IndexController extends IndexBaseController
14 | {
15 | /**
16 | * @throws Exception
17 | */
18 | public function index(): string
19 | {
20 | $this->index['name'] = '演示首页';
21 | $this->index['title'] = '首页演示,自定义即可';
22 | return $this->fetch();
23 | }
24 |
25 | /**
26 | * @throws Exception
27 | */
28 | public function product(): string
29 | {
30 | $this->index['name'] = '演示产品';
31 | $this->index['title'] = '这是产品的演示页面,啊啊啊啊啊,这个地方可以用富文本,自己合理安排就行。。';
32 |
33 | return $this->fetch();
34 | }
35 |
36 | /**
37 | * @throws Exception
38 | */
39 | public function about(): string
40 | {
41 | $this->index['name'] = '演示关于';
42 | $this->index['title'] = '这是关于我们的演示页面,啊啊啊啊啊,这个地方可以用富文本,自己合理安排就行。。';
43 |
44 | return $this->fetch();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/index/controller/UserController.php:
--------------------------------------------------------------------------------
1 | fetch();
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/app/index/exception/IndexServiceException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\index\exception;
11 |
12 |
13 | use Exception;
14 |
15 | class IndexServiceException extends Exception
16 | {
17 |
18 | }
--------------------------------------------------------------------------------
/app/index/middleware.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\index\service;
11 |
12 |
13 | use app\common\model\User;
14 | use app\index\exception\IndexServiceException;
15 |
16 | class AuthService extends IndexBaseService
17 | {
18 |
19 | protected $model;
20 | public function __construct()
21 | {
22 | $this->model = new User();
23 | }
24 |
25 | /**
26 | * 用户登录
27 | * @param $username
28 | * @param $password
29 | * @return User|array|\think\Model
30 | * @throws IndexServiceException
31 | */
32 | public function login($username,$password)
33 | {
34 |
35 | $user =$this->model->where('username' ,'=', $username)->findOrEmpty();
36 |
37 | if ($user->isEmpty()) {
38 | throw new IndexServiceException('用户不存在');
39 | }
40 |
41 | if (!password_verify($password, base64_decode($user->password))) {
42 | throw new IndexServiceException('密码错误');
43 | }
44 |
45 | if ((int)$user->status !== 1) {
46 | throw new IndexServiceException('用户被冻结');
47 | }
48 | return $user;
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/app/index/service/IndexBaseService.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 |
10 | namespace app\index\service;
11 |
12 |
13 | class IndexBaseService
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/app/middleware.php:
--------------------------------------------------------------------------------
1 | ExceptionHandle::class,
7 | ];
8 |
--------------------------------------------------------------------------------
/app/service.php:
--------------------------------------------------------------------------------
1 | =7.4",
24 | "topthink/framework": "^6.0.0",
25 | "topthink/think-orm": "^2.0",
26 | "topthink/think-multi-app": "^1.0",
27 | "topthink/think-view": "^1.0",
28 | "topthink/think-migration": "^3.0",
29 | "topthink/think-captcha": "^3.0",
30 | "phpoffice/phpspreadsheet": "^1.16",
31 | "mk-j/php_xlsxwriter": "^0.38.0",
32 | "ext-openssl": "*",
33 | "ext-json": "*",
34 | "ext-curl": "*",
35 | "topthink/think-filesystem": "^2.0"
36 | },
37 | "require-dev": {
38 | "symfony/var-dumper": "^4.2",
39 | "topthink/think-trace": "^1.0"
40 | },
41 | "autoload": {
42 | "psr-4": {
43 | "app\\": "app"
44 | },
45 | "psr-0": {
46 | "": "extend/"
47 | }
48 | },
49 | "config": {
50 | "preferred-install": "dist"
51 | },
52 | "scripts": {
53 | "post-autoload-dump": [
54 | "@php think service:discover",
55 | "@php think vendor:publish",
56 | "@php think init:env"
57 | ]
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | env('app.host', ''),
9 | // 应用的命名空间
10 | 'app_namespace' => '',
11 | // 是否启用路由
12 | 'with_route' => true,
13 | // 是否启用事件
14 | 'with_event' => true,
15 | // 默认应用
16 | 'default_app' => 'index',
17 | // 默认时区
18 | 'default_timezone' => env('app.default_timezone', 'Asia/Shanghai'),
19 |
20 | // 应用映射(自动多应用模式有效)
21 | 'app_map' => [],
22 | // 域名绑定(自动多应用模式有效)
23 | 'domain_bind' => [],
24 | // 禁止URL访问的应用列表(自动多应用模式有效)
25 | 'deny_app_list' => [
26 | 'command',
27 | 'common',
28 | 'facade',
29 | 'service',
30 | ],
31 |
32 | // 异常页面的模板文件
33 | 'exception_tmpl' => app()->getAppPath() . 'common/exception/tpl/think_exception.tpl',
34 |
35 | // 错误显示信息,非调试模式有效
36 | 'error_message' => '系统繁忙,请稍后再试~',
37 | // 显示错误信息
38 | 'show_error_msg' => false,
39 | 'app_key' => env('app.app_key', ''),
40 | ];
41 |
--------------------------------------------------------------------------------
/config/cache.php:
--------------------------------------------------------------------------------
1 | env('cache.driver', 'file'),
9 |
10 | // 缓存连接方式配置
11 | 'stores' => [
12 | 'file' => [
13 | // 驱动方式
14 | 'type' => 'File',
15 | // 缓存保存目录
16 | 'path' => '',
17 | // 缓存前缀
18 | 'prefix' => '',
19 | // 缓存有效期 0表示永久缓存
20 | 'expire' => 0,
21 | // 缓存标签前缀
22 | 'tag_prefix' => 'tag:',
23 | // 序列化机制 例如 ['serialize', 'unserialize']
24 | 'serialize' => [],
25 | ],
26 | // redis缓存
27 | 'redis' => [
28 | // 驱动方式
29 | 'type' => 'redis',
30 | // 服务器地址
31 | 'host' => env('redis.redis_host', '127.0.0.1'),
32 | 'port' => env('redis.redis_port', 6379),
33 | 'password' => env('redis.redis_password', ''),
34 | 'select' => env('redis.redis_select', 0),
35 | ],
36 | // 更多的缓存连接
37 | ],
38 | ];
39 |
--------------------------------------------------------------------------------
/config/captcha.php:
--------------------------------------------------------------------------------
1 | 5,
9 | // 验证码字符集合
10 | 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
11 | // 验证码过期时间
12 | 'expire' => 1800,
13 | // 是否使用中文验证码
14 | 'useZh' => false,
15 | // 是否使用算术验证码
16 | 'math' => false,
17 | // 是否使用背景图
18 | 'useImgBg' => false,
19 | //验证码字符大小
20 | 'fontSize' => 25,
21 | // 是否使用混淆曲线
22 | 'useCurve' => true,
23 | //是否添加杂点
24 | 'useNoise' => true,
25 | // 验证码字体 不设置则随机
26 | 'fontttf' => '',
27 | //背景颜色
28 | 'bg' => [243, 251, 254],
29 | // 验证码图片高度
30 | 'imageH' => 48,
31 | // 验证码图片宽度
32 | 'imageW' => 240,
33 |
34 | // 添加额外的验证码设置
35 | // verify => [
36 | // 'length'=>4,
37 | // ...
38 | //],
39 | ];
40 |
--------------------------------------------------------------------------------
/config/console.php:
--------------------------------------------------------------------------------
1 | [
14 | // 测试指令
15 | 'test' => \app\command\Test::class,
16 | // 初始化env文件
17 | 'init:env' => InitEnv::class,
18 | // 生成新的app_key
19 | 'generate:app_key' => GenerateAppKey::class,
20 | // 生成新的jwt_key
21 | 'generate:jwt_key' => GenerateJwtKey::class,
22 | // 重置后台管理员密码
23 | 'reset:admin_password' => ResetAdminPassword::class
24 | ],
25 | ];
26 |
--------------------------------------------------------------------------------
/config/cookie.php:
--------------------------------------------------------------------------------
1 | 0,
8 | // cookie 保存路径
9 | 'path' => '/',
10 | // cookie 有效域名
11 | 'domain' => '',
12 | // cookie 启用安全传输
13 | 'secure' => false,
14 | // httponly设置
15 | 'httponly' => false,
16 | // 是否使用 setcookie
17 | 'setcookie' => true,
18 | ];
19 |
--------------------------------------------------------------------------------
/config/lang.php:
--------------------------------------------------------------------------------
1 | env('lang.default_lang', 'zh-cn'),
9 | // 允许的语言列表
10 | 'allow_lang_list' => [],
11 | // 多语言自动侦测变量名
12 | 'detect_var' => 'lang',
13 | // 是否使用Cookie记录
14 | 'use_cookie' => true,
15 | // 多语言cookie变量
16 | 'cookie_var' => 'app_lang',
17 | // 扩展语言包
18 | 'extend_list' => [],
19 | // Accept-Language转义为对应语言包名称
20 | 'accept_language' => [
21 | 'zh-hans-cn' => 'zh-cn',
22 | ],
23 | // 是否支持语言分组
24 | 'allow_group' => false,
25 | ];
26 |
--------------------------------------------------------------------------------
/config/log.php:
--------------------------------------------------------------------------------
1 | env('log.channel', 'file'),
9 | // 日志记录级别
10 | 'level' => [],
11 | // 日志类型记录的通道 ['error'=>'email',...]
12 | 'type_channel' => [],
13 | // 关闭全局日志写入
14 | 'close' => false,
15 | // 全局日志处理 支持闭包
16 | 'processor' => null,
17 |
18 | // 日志通道列表
19 | 'channels' => [
20 | 'file' => [
21 | // 日志记录方式
22 | 'type' => 'File',
23 | // 日志保存目录
24 | 'path' => '',
25 | // 单文件日志写入
26 | 'single' => false,
27 | // 独立日志级别
28 | 'apart_level' => [],
29 | // 最大日志文件数量
30 | 'max_files' => 0,
31 | // 使用JSON格式记录
32 | 'json' => false,
33 | // 日志处理
34 | 'processor' => null,
35 | // 关闭通道日志写入
36 | 'close' => false,
37 | // 日志输出格式化
38 | 'format' => '[%s][%s] %s',
39 | // 是否实时写入
40 | 'realtime_write' => false,
41 | ],
42 | // 其它日志通道配置
43 | ],
44 |
45 | ];
46 |
--------------------------------------------------------------------------------
/config/map.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | return [
10 | // 高德地图
11 | 'amap' => [
12 | //
13 | 'web_api_key' => '7d1edf73d7afe85dcc33fbaaba935512',
14 | 'js_api_key' => 'cccf8ea926e153be0a013d55edd47c11',
15 | ],
16 | ];
--------------------------------------------------------------------------------
/config/middleware.php:
--------------------------------------------------------------------------------
1 | [],
6 | // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
7 | 'priority' => [],
8 | ];
9 |
--------------------------------------------------------------------------------
/config/route.php:
--------------------------------------------------------------------------------
1 | '/',
9 | // URL伪静态后缀
10 | 'url_html_suffix' => 'html',
11 | // URL普通方式参数 用于自动生成
12 | 'url_common_param' => true,
13 | // 是否开启路由延迟解析
14 | 'url_lazy_route' => false,
15 | // 是否强制使用路由
16 | 'url_route_must' => false,
17 | // 合并路由规则
18 | 'route_rule_merge' => false,
19 | // 路由是否完全匹配
20 | 'route_complete_match' => false,
21 | // 访问控制器层名称
22 | 'controller_layer' => 'controller',
23 | // 空控制器名
24 | 'empty_controller' => 'Error',
25 | // 是否使用控制器后缀
26 | 'controller_suffix' => true,
27 | // 默认的路由变量规则
28 | 'default_route_pattern' => '[\w\.]+',
29 | // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
30 | 'request_cache' => false,
31 | // 请求缓存有效期
32 | 'request_cache_expire' => null,
33 | // 全局请求缓存排除规则
34 | 'request_cache_except' => [],
35 | // 默认控制器名
36 | 'default_controller' => 'Index',
37 | // 默认操作名
38 | 'default_action' => 'index',
39 | // 操作方法后缀
40 | 'action_suffix' => '',
41 | // 默认JSONP格式返回的处理方法
42 | 'default_jsonp_handler' => 'jsonpReturn',
43 | // 默认JSONP处理方法
44 | 'var_jsonp_handler' => 'callback',
45 | ];
46 |
--------------------------------------------------------------------------------
/config/session.php:
--------------------------------------------------------------------------------
1 | 'AppSId',
9 | // SESSION_ID的提交变量,解决flash上传跨域
10 | 'var_session_id' => '',
11 | // 驱动方式 支持file cache
12 | 'type' => 'file',
13 | // 存储连接标识 当type使用cache的时候有效
14 | 'store' => null,
15 | // 过期时间
16 | 'expire' => 1440,
17 | // 前缀
18 | 'prefix' => '',
19 | ];
20 |
--------------------------------------------------------------------------------
/config/trace.php:
--------------------------------------------------------------------------------
1 | 'Console',
8 | // 读取的日志通道名
9 | 'channel' => '',
10 | ];
11 |
--------------------------------------------------------------------------------
/config/view.php:
--------------------------------------------------------------------------------
1 | 'Think',
9 | // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
10 | 'auto_rule' => 1,
11 | // 模板目录名
12 | 'view_dir_name' => 'view',
13 | // 模板后缀
14 | 'view_suffix' => 'html',
15 | // 模板文件名分隔符
16 | 'view_depr' => DIRECTORY_SEPARATOR,
17 | // 模板引擎普通标签开始标记
18 | 'tpl_begin' => '{',
19 | // 模板引擎普通标签结束标记
20 | 'tpl_end' => '}',
21 | // 标签库标签开始标记
22 | 'taglib_begin' => '{',
23 | // 标签库标签结束标记
24 | 'taglib_end' => '}',
25 | 'default_filter' => 'htmlentities_view',
26 | ];
27 |
--------------------------------------------------------------------------------
/database/example/README.md:
--------------------------------------------------------------------------------
1 | # 常用表迁移文件
2 | > 常用表迁移文件代码参考,可自行复制到迁移文件内使用。
3 |
4 | ###
--------------------------------------------------------------------------------
/database/migrations/20200806100513_admin_log.php:
--------------------------------------------------------------------------------
1 | table('admin_log', ['comment' => '后台操作日志', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
14 | $table
15 | ->addColumn('admin_user_id', 'integer', ['signed' => false, 'limit' => 10, 'comment' => '用户'])
16 | ->addColumn('name', 'string', ['limit' => 30, 'default' => '', 'comment' => '操作'])
17 | ->addColumn('url', 'string', ['limit' => 100, 'default' => '', 'comment' => 'URL'])
18 | ->addColumn('log_method', 'string', ['limit' => 8, 'default' => '不记录', 'comment' => '记录日志方法'])
19 | ->addColumn('log_ip', 'string', ['limit' => 20, 'default' => '', 'comment' => '操作IP'])
20 | ->addColumn('create_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '创建时间'])
21 | ->addColumn('update_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '更新时间'])
22 | ->addColumn('delete_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '删除时间'])
23 | ->create();
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/database/migrations/20200806100516_admin_log_data.php:
--------------------------------------------------------------------------------
1 | table('admin_log_data', ['comment' => '后台操作日志数据', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
16 | $table
17 | ->addColumn('admin_log_id', 'integer', ['signed' => false, 'limit' => 10, 'comment' => '日志ID'])
18 | ->addColumn('data', 'text', ['limit' => MysqlAdapter::TEXT_LONG, 'comment' => '日志内容'])
19 | ->addColumn('create_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '创建时间'])
20 | ->addColumn('update_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '更新时间'])
21 | ->addColumn('delete_time', 'integer', ['signed' => false, 'limit' => 10, 'default' => 0, 'comment' => '删除时间'])
22 | ->create();
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/database/migrations/20210908031808_test.php:
--------------------------------------------------------------------------------
1 | table('test', ['comment' => '测试', 'engine' => 'InnoDB', 'encoding' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci']);
13 | $table
14 | ->addColumn('avatar', 'string', ['limit' => 255, 'default' => '/static/index/images/avatar.png', 'comment' => '头像'])
15 | ->addColumn('username', 'string', ['limit' => 30, 'default' => '', 'comment' => '用户名'])
16 | ->addColumn('nickname', 'string', ['limit' => 30, 'default' => '', 'comment' => '昵称'])
17 | ->addColumn('mobile', 'string', ['limit' => 11, 'default' => '', 'comment' => '手机号'])
18 | ->addColumn('user_level_id', 'integer', ['limit' => 10, 'default' => 1, 'comment' => '用户等级'])
19 | ->addColumn('password', 'string', ['limit' => 255, 'default' => base64_encode(password_hash('_default__password_', 1)), 'comment' => '密码'])
20 | ->addColumn('status', 'boolean', ['limit' => 1, 'default' => 1, 'comment' => '是否启用'])
21 | ->addColumn('lng', 'decimal', ['precision' => 14, 'scale' => 8, 'default' => 116, 'comment' => '经度'])// 测试地图
22 | ->addColumn('lat', 'decimal', ['precision' => 14, 'scale' => 8, 'default' => 37, 'comment' => '纬度'])
23 | ->addColumn('slide', 'text', [ 'comment' => '相册'])// 测试多图上传
24 | ->addColumn('content', 'text', [ 'comment' => '内容'])// 测试编辑器
25 | ->addColumn('create_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '创建时间'])
26 | ->addColumn('update_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '更新时间'])
27 | ->addColumn('delete_time', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '删除时间'])
28 | ->create();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/extend/generate/exception/GenerateException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\exception;
10 |
11 | use Exception;
12 |
13 | class GenerateException extends Exception
14 | {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/extend/generate/field/Color.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Color extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
22 |
30 |
31 | \n
32 | EOF;
33 |
34 | public static array $rules = [
35 | 'required' => '非空',
36 | 'color16' => '16进制颜色',
37 | ];
38 |
39 | public static function create($data): string
40 | {
41 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/extend/generate/field/Date.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Date extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
22 |
23 | \n
24 | EOF;
25 |
26 | public static function create($data): string
27 | {
28 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
29 | }
30 | }
--------------------------------------------------------------------------------
/extend/generate/field/DateRange.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class DateRange extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
24 |
25 | \n
26 | EOF;
27 |
28 | public static function create($data): string
29 | {
30 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
31 | }
32 | }
--------------------------------------------------------------------------------
/extend/generate/field/Datetime.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Datetime extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
23 |
24 | \n
25 | EOF;
26 |
27 | public static function create($data): string
28 | {
29 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
30 | }
31 | }
--------------------------------------------------------------------------------
/extend/generate/field/DatetimeRange.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class DatetimeRange extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
25 |
26 | \n
27 | EOF;
28 |
29 | public static function create($data): string
30 | {
31 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
32 | }
33 | }
--------------------------------------------------------------------------------
/extend/generate/field/Editor.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Editor extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
{\$data.[FIELD_NAME]|raw|default='
[FIELD_DEFAULT]
'}
16 |
17 |
18 |
32 | \n
33 | EOF;
34 |
35 | /**
36 | * @var string 富文本字段添加处理
37 | */
38 | public static string $controllerAddCode = <<param(false)['[FIELD_NAME]'];
40 | \n
41 | EOF;
42 | /**
43 | * @var string 富文本字段修改处理
44 | */
45 | public static string $controllerEditCode = <<param(false)['[FIELD_NAME]'];
47 | \n
48 | EOF;
49 |
50 | public static function create($data): string
51 | {
52 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
53 | }
54 | }
--------------------------------------------------------------------------------
/extend/generate/field/Email.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Email extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'email' => '邮箱',
23 | ];
24 |
25 | public static function create($data): string
26 | {
27 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
28 | }
29 | }
--------------------------------------------------------------------------------
/extend/generate/field/File.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace generate\field;
7 |
8 | class File extends Field
9 | {
10 |
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
18 |
19 |
22 | \n
23 | EOF;
24 |
25 | public static function create($data): string
26 | {
27 | $html = self::$html;
28 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($data['form_name'], $data['field_name']), $html);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/extend/generate/field/Icon.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Icon extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
26 |
27 |
30 | \n
31 | EOF;
32 |
33 | public static function create($data): string
34 | {
35 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
36 | }
37 | }
--------------------------------------------------------------------------------
/extend/generate/field/IdCard.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class IdCard extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'idCard' => '身份证',
23 | ];
24 |
25 |
26 | public static function create($data): string
27 | {
28 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
29 | }
30 | }
--------------------------------------------------------------------------------
/extend/generate/field/Image.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Image extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
23 |
24 | EOF;
25 |
26 | public static function create($data): string
27 | {
28 | $html = self::$html;
29 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), $html);
30 | }
31 | }
--------------------------------------------------------------------------------
/extend/generate/field/Ip.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Ip extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'ipv4' => 'IPV4',
23 | 'ipv6' => 'IPV6',
24 | 'ip' => 'IP',
25 | ];
26 |
27 |
28 | public static function create($data): string
29 | {
30 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
31 | }
32 | }
--------------------------------------------------------------------------------
/extend/generate/field/Mobile.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Mobile extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'mobile' => '手机号',
23 | ];
24 |
25 | public static function create($data): string
26 | {
27 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
28 | }
29 | }
--------------------------------------------------------------------------------
/extend/generate/field/MultiFile.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class MultiFile extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
20 |
21 |
22 | EOF;
23 |
24 | public static function create($data): string
25 | {
26 | $html = self::$html;
27 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($data['form_name'], $data['field_name']), $html);
28 | }
29 | }
--------------------------------------------------------------------------------
/extend/generate/field/MultiImage.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class MultiImage extends Field
10 | {
11 | public static string $html = <<
14 | [FORM_NAME]
15 |
24 |
25 | EOF;
26 |
27 | public static function create($data): string
28 | {
29 | $html = self::$html;
30 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($data['form_name'], $data['field_name']), $html);
31 | }
32 | }
--------------------------------------------------------------------------------
/extend/generate/field/MultiSelect.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class MultiSelect extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | [OPTION_DATA]
18 |
19 |
20 |
21 |
24 | \n
25 | EOF;
26 |
27 | public static function create($data): string
28 | {
29 | $html = self::$html;
30 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[OPTION_DATA]'), array($data['form_name'], $data['field_name'] ?? '', $data['option_data'] ?? ''), $html);
31 | }
32 | }
--------------------------------------------------------------------------------
/extend/generate/field/Number.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Number extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
19 |
20 |
28 | \n
29 | EOF;
30 |
31 | public static array $rules = [
32 | //非空
33 | 'required' => '非空',
34 | //纯数字
35 | 'number' => '纯数字',
36 | ];
37 |
38 | public static function create($data): string
39 | {
40 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
41 | }
42 |
43 |
44 | }
--------------------------------------------------------------------------------
/extend/generate/field/Password.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Password extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'number6' => '6位纯数字',
23 | 'simplePassword' => '简单密码',
24 | 'middlePassword' => '中等密码',
25 | 'complexPassword' => '复杂密码',
26 | ];
27 |
28 | public static function create($data): string
29 | {
30 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
31 | }
32 | }
--------------------------------------------------------------------------------
/extend/generate/field/Select.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Select extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 | [OPTION_DATA]
19 |
20 |
21 |
22 |
27 | \n
28 | EOF;
29 |
30 | public static function create($data): string
31 | {
32 | $html = self::$html;
33 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[OPTION_DATA]'), array($data['form_name'], $data['field_name'] ?? '', $data['option_data'] ?? ''), $html);
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/extend/generate/field/SwitchField.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace generate\field;
7 |
8 | class SwitchField extends Field
9 | {
10 | public static string $html = <<
12 | [FORM_NAME]
13 |
14 |
16 |
17 |
18 |
19 |
30 | \n
31 | EOF;
32 |
33 |
34 | public static function create($data): string
35 | {
36 | $html = self::$html;
37 | //switch开的文字
38 | if (isset($data['on_text'])) {
39 | $html = str_replace('[ON_TEXT]', $data['on_text'], $html);
40 | } else {
41 | $html = str_replace('[ON_TEXT]', '是', $html);
42 | }
43 | //switch关的文字
44 | if (isset($data['off_text'])) {
45 | $html = str_replace('[OFF_TEXT]', $data['off_text'], $html);
46 | } else {
47 | $html = str_replace('[OFF_TEXT]', '否', $html);
48 | }
49 |
50 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), $html);
51 | }
52 | }
--------------------------------------------------------------------------------
/extend/generate/field/Text.php:
--------------------------------------------------------------------------------
1 |
4 | */
5 |
6 | namespace generate\field;
7 |
8 | class Text extends Field
9 | {
10 |
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static function create($data): string
21 | {
22 | return str_replace(
23 | array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'),
24 | array($data['form_name'], $data['field_name'], $data['field_default']),
25 | self::$html);
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/extend/generate/field/Textarea.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Textarea extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static function create($data): string
21 | {
22 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]', '[ROWS]'), array($data['form_name'], $data['field_name'], $data['field_default'], $data['rows'] ?? 3), self::$html);
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/extend/generate/field/Time.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Time extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
18 |
24 | \n
25 | EOF;
26 |
27 | public static array $rules = [
28 | 'required' => '非空',
29 | 'time' => '时间',
30 | ];
31 |
32 |
33 | public static function create($data): string
34 | {
35 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
36 | }
37 | }
--------------------------------------------------------------------------------
/extend/generate/field/TimeRange.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class TimeRange extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
18 |
25 | \n
26 | EOF;
27 |
28 | public static array $rules = [
29 | 'required' => '非空',
30 | 'time_range' => '时间范围',
31 | ];
32 |
33 | public static function create($data): string
34 | {
35 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
36 | }
37 | }
--------------------------------------------------------------------------------
/extend/generate/field/Url.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Url extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 | \n
18 | EOF;
19 |
20 | public static array $rules = [
21 | 'required' => '非空',
22 | 'url' => 'URL',
23 | ];
24 |
25 |
26 | public static function create($data): string
27 | {
28 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
29 | }
30 | }
--------------------------------------------------------------------------------
/extend/generate/field/Video.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Video extends Field
10 | {
11 | public static string $html = <<
13 | [FORM_NAME]
14 |
15 |
16 |
17 |
18 |
19 |
22 | \n
23 | EOF;
24 |
25 | public static function create($data): string
26 | {
27 | $html = self::$html;
28 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]'), array($data['form_name'], $data['field_name']), $html);
29 | }
30 | }
--------------------------------------------------------------------------------
/extend/generate/field/Year.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class Year extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
19 |
25 | \n
26 | EOF;
27 | public static array $rules = [
28 | 'required' => '非空',
29 | 'year' => '年',
30 | ];
31 |
32 | public static function create($data): string
33 | {
34 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
35 | }
36 | }
--------------------------------------------------------------------------------
/extend/generate/field/YearMonth.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class YearMonth extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
19 |
25 | \n
26 | EOF;
27 |
28 | public static array $rules = [
29 | 'required' => '非空',
30 | 'year_month' => '年月',
31 | ];
32 |
33 | public static function create($data): string
34 | {
35 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
36 | }
37 | }
--------------------------------------------------------------------------------
/extend/generate/field/YearMonthRange.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class YearMonthRange extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
25 | \n
26 | EOF;
27 |
28 | public static array $rules = [
29 | 'required' => '非空',
30 | 'year_month_range' => '年月范围',
31 | ];
32 |
33 |
34 | public static function create($data): string
35 | {
36 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
37 | }
38 | }
--------------------------------------------------------------------------------
/extend/generate/field/YearRange.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | namespace generate\field;
8 |
9 | class YearRange extends Field
10 | {
11 |
12 | public static string $html = <<
14 | [FORM_NAME]
15 |
16 |
17 |
18 |
19 |
26 | \n
27 | EOF;
28 |
29 | public static array $rules = [
30 | 'required' => '非空',
31 | 'year' => '年范围',
32 | ];
33 |
34 | public static function create($data): string
35 | {
36 | return str_replace(array('[FORM_NAME]', '[FIELD_NAME]', '[FIELD_DEFAULT]'), array($data['form_name'], $data['field_name'], $data['field_default']), self::$html);
37 | }
38 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/AdminController.stub:
--------------------------------------------------------------------------------
1 | isPost()) {
12 | $param = $request->param();
13 | $validate_result = $validate->scene('admin_add')->check($param);
14 | if (!$validate_result) {
15 | return admin_error($validate->getError());
16 | }
17 | [ADD_FIELD_CODE]
18 | $result = $model::create($param);
19 |
20 | $url = URL_BACK;
21 | if (isset($param['_create']) && (int)$param['_create'] === 1) {
22 | $url = URL_RELOAD;
23 | }
24 | return $result ? admin_success('添加成功', [], $url) : admin_error();
25 | }
26 | [RELATION_2]
27 | return $this->fetch();
28 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_del.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 删除
3 | * @param mixed $id
4 | * @param [MODEL_NAME] $model
5 | * @return Json
6 | */
7 | public function del($id, [MODEL_NAME] $model): Json
8 | {
9 | $check = $model->inNoDeletionIds($id);
10 | if (false !== $check) {
11 | return admin_error('ID为' . $check . '的数据不能被删除');
12 | }
13 |
14 | $result = $model::destroy(static function ($query) use ($id) {
15 | /** @var Query $query */
16 | $query->whereIn('id', $id);
17 | });
18 |
19 | return $result ? admin_success('删除成功', [], URL_RELOAD) : admin_error('删除失败');
20 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_disable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 禁用
3 | * @param mixed $id
4 | * @param [MODEL_NAME] $model
5 | * @return Json
6 | */
7 | public function disable($id, [MODEL_NAME] $model): Json
8 | {
9 | $result = $model->whereIn('id', $id)->update(['status' => 0]);
10 | return $result ? admin_success('操作成功', [], URL_RELOAD) : admin_error();
11 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_edit.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 修改
3 | * @param $id
4 | * @param Request $request
5 | * @param [MODEL_NAME] $model
6 | * @param [VALIDATE_NAME]Validate $validate
7 | * @return string|Json
8 | * @throws Exception
9 | */
10 | public function edit($id, Request $request, [MODEL_NAME] $model, [VALIDATE_NAME]Validate $validate)
11 | {
12 | $data = $model->findOrEmpty($id);
13 | if ($request->isPost()) {
14 | $param = $request->param();
15 | $check = $validate->scene('admin_edit')->check($param);
16 | if (!$check) {
17 | return admin_error($validate->getError());
18 | }
19 | [EDIT_FIELD_CODE]
20 | $result = $data->save($param);
21 |
22 | return $result ? admin_success('修改成功', [], URL_BACK) : admin_error('修改失败');
23 | }
24 |
25 | $this->assign([
26 | 'data' => $data,
27 | [RELATION_3]
28 | ]);
29 |
30 | return $this->fetch('add');
31 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_enable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 启用
3 | * @param mixed $id
4 | * @param [MODEL_NAME] $model
5 | * @return Json
6 | */
7 | public function enable($id, [MODEL_NAME] $model): Json
8 | {
9 | $result = $model->whereIn('id', $id)->update(['status' => 1]);
10 | return $result ? admin_success('操作成功', [], URL_RELOAD) : admin_error();
11 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_export.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 导出
3 | * @param Request $request
4 | * @param [MODEL_NAME] $model
5 | * @throws Exception
6 | */
7 | public function export(Request $request, [MODEL_NAME] $model)
8 | {
9 | $param = $request->param();
10 | $data = $model[RELATION_WITH]->scope('where', $param)->select();
11 |
12 | $header = [[HEADER_LIST]];
13 | $body = [];
14 | foreach ($data as $item) {
15 | $record = [];
16 | [BODY_ITEM]
17 | $body[] = $record;
18 | }
19 | $this->exportData($header, $body, '[FILE_NAME]-' . date('YmdHis'));
20 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_import.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 导入
3 | * @param Request $request
4 | * @return Json
5 | */
6 | public function import(Request $request): Json
7 | {
8 | $param = $request->param();
9 | $field_name_list = [[FILED_NAME_LIST]];
10 | if (isset($param['action']) && $param['action'] === 'download_example') {
11 | $this->downloadExample($field_name_list);
12 | }
13 |
14 | $field_list = [[FILED_LIST]];
15 | $result = $this->importData('file','[TABLE_NAME]',$field_list);
16 |
17 | return true === $result ? admin_success('操作成功', [], URL_RELOAD) : admin_error($result);
18 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/action_index.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 列表
3 | * @param Request $request
4 | * @param [MODEL_NAME] $model
5 | * @return string
6 | * @throws Exception
7 | */
8 | public function index(Request $request, [MODEL_NAME] $model): string
9 | {
10 | $param = $request->param();
11 | $data = $model[RELATION_WITH]->scope('where', $param)
12 | ->paginate([
13 | 'list_rows' => $this->admin['admin_list_rows'],
14 | 'var_page' => 'page',
15 | 'query' => $request->get(),
16 | ]);
17 | // 关键词,排序等赋值
18 | $this->assign($request->get());
19 |
20 | $this->assign([
21 | 'data' => $data,
22 | 'page' => $data->render(),
23 | 'total' => $data->total(),
24 | [SEARCH_DATA_LIST]
25 | ]);
26 | return $this->fetch();
27 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/relation_assign_1.stub:
--------------------------------------------------------------------------------
1 | $this->assign([
2 | [RELATION_LIST]
3 | ]);
4 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/relation_data_list.stub:
--------------------------------------------------------------------------------
1 | '[LIST_NAME]' => [CLASS_NAME]::select(),
2 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/relation_delete.stub:
--------------------------------------------------------------------------------
1 | // 关联数据删除限制
2 | $msg_[FIELD_NAME] = '下有[FORM_NAME]数据,请删除[FORM_NAME]后再进行删除操作';
3 | if(is_array($id)){
4 | foreach ($id as $item){
5 | $data = $model::get($item);
6 | if($data->school->count()>0){
7 | return error($data->name.$msg_[FIELD_NAME]);
8 | }
9 | }
10 | }else{
11 | $data = $model::get($id);
12 | if($data->school->count()>0){
13 | return error($data->name.$msg_[FIELD_NAME]);
14 | }
15 | }
--------------------------------------------------------------------------------
/extend/generate/stub/admin_controller/relation_with.stub:
--------------------------------------------------------------------------------
1 | ->with([[WITH_LIST]])
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/add/customer_multi_select_data.stub:
--------------------------------------------------------------------------------
1 | {foreach [FIELD_LIST] as $key=>$value}
2 | {$value}
3 | {/foreach}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/add/customer_select_data.stub:
--------------------------------------------------------------------------------
1 | {foreach [FIELD_LIST] as $key=>$value}
2 | {$value}
3 | {/foreach}
4 |
5 |
6 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/add/relation_select_data.stub:
--------------------------------------------------------------------------------
1 | {foreach name='[DATA_LIST]' id='item'}
2 |
3 | {$item.[RELATION_SHOW]}
4 |
5 | {/foreach}
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/create.stub:
--------------------------------------------------------------------------------
1 |
2 | 添加
3 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/del1.stub:
--------------------------------------------------------------------------------
1 |
2 | 删除
3 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/del2.stub:
--------------------------------------------------------------------------------
1 |
2 | [OPERATION_DEL_ICON]
3 | [OPERATION_DEL_TEXT]
4 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/enable1.stub:
--------------------------------------------------------------------------------
1 |
2 | 启用
3 |
4 |
5 |
6 | 禁用
7 |
8 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/enable2.stub:
--------------------------------------------------------------------------------
1 | {if $item.status==1}
2 |
3 | [OPERATION_DISABLE_ICON]
4 | [OPERATION_DISABLE_TEXT]
5 |
6 | {else/}
7 |
8 | [OPERATION_ENABLE_ICON]
9 | [OPERATION_ENABLE_TEXT]
10 |
11 | {/if}
12 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/export.stub:
--------------------------------------------------------------------------------
1 |
2 | 导出
3 |
4 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/filter.stub:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/refresh.stub:
--------------------------------------------------------------------------------
1 |
2 | 刷新
3 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/select1.stub:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/select2.stub:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/extend/generate/stub/admin_view/index/sort.stub:
--------------------------------------------------------------------------------
1 |
2 |
3 | 排序字段
4 | [SORT_FIELD_LIST]
5 |
6 |
7 |
8 |
9 |
10 | 排序方式
11 | 倒序
12 | 正序
13 |
14 |
15 |
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/ApiController.stub:
--------------------------------------------------------------------------------
1 | scene('api_add')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | $result = $service->createData($this->param);
15 |
16 | return $result ? api_success() : api_error();
17 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_del.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 删除
3 | * @param [SERVICE_NAME]Service $service
4 | * @param [VALIDATE_NAME]Validate $validate
5 | * @return Json
6 | */
7 | public function del([SERVICE_NAME]Service $service, [VALIDATE_NAME]Validate $validate): Json
8 | {
9 | $check = $validate->scene('api_del')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | try {
15 | $service->deleteData($this->id);
16 | return api_success();
17 | } catch (ApiServiceException $e) {
18 | return api_error($e->getMessage());
19 | }
20 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_disable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 禁用
3 | * @param [SERVICE_NAME]Service $service
4 | * @param [VALIDATE_NAME]Validate $validate
5 | * @return Json
6 | */
7 | public function disable([SERVICE_NAME]Service $service, [VALIDATE_NAME]Validate $validate): Json
8 | {
9 | $check = $validate->scene('api_disable')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | try {
15 | $service->disableData($this->id);
16 | return api_success();
17 | } catch (ApiServiceException $e) {
18 | return api_error($e->getMessage());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_edit.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 修改
3 | * @param [SERVICE_NAME]Service $service
4 | * @param [VALIDATE_NAME]Validate $validate
5 | * @return Json
6 | */
7 | public function edit([SERVICE_NAME]Service $service, [VALIDATE_NAME]Validate $validate): Json
8 | {
9 | $check = $validate->scene('api_edit')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | try {
15 | $service->updateData($this->id, $this->param);
16 | return api_success();
17 | } catch (ApiServiceException $e) {
18 | return api_error($e->getMessage());
19 | }
20 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_enable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 启用
3 | * @param [SERVICE_NAME]Service $service
4 | * @param [VALIDATE_NAME]Validate $validate
5 | * @return Json
6 | */
7 | public function enable([SERVICE_NAME]Service $service, [VALIDATE_NAME]Validate $validate): Json
8 | {
9 | $check = $validate->scene('api_enable')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | try {
15 | $service->enableData($this->id);
16 | return api_success();
17 | } catch (ApiServiceException $e) {
18 | return api_error($e->getMessage());
19 | }
20 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_index.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 列表
3 | * @param [SERVICE_NAME]Service $service
4 | * @return Json
5 | */
6 | public function index([SERVICE_NAME]Service $service): Json
7 | {
8 | try {
9 | $data = $service->getList($this->param, $this->page, $this->limit);
10 | $result = [
11 | '[TABLE_NAME]' => $data,
12 | ];
13 |
14 | return api_success($result);
15 | } catch (ApiServiceException $e) {
16 | return api_error($e->getMessage());
17 | }
18 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_controller/api_info.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 详情
3 | * @param [VALIDATE_NAME]Validate $validate
4 | * @param [SERVICE_NAME]Service $service
5 | * @return Json
6 | */
7 | public function info([SERVICE_NAME]Validate $validate, [VALIDATE_NAME]Service $service): Json
8 | {
9 | $check = $validate->scene('api_info')->check($this->param);
10 | if (!$check) {
11 | return api_error($validate->getError());
12 | }
13 |
14 | try {
15 |
16 | $result = $service->getDataInfo($this->id);
17 | return api_success([
18 | '[TABLE_NAME]' => $result,
19 | ]);
20 |
21 | } catch (ApiServiceException $e) {
22 | return api_error($e->getMessage());
23 | }
24 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/ApiService.stub:
--------------------------------------------------------------------------------
1 | model = new [MODEL_NAME]();
21 | }
22 |
23 | [SERVICE_INDEX]
24 |
25 | [SERVICE_ADD]
26 |
27 | [SERVICE_INFO]
28 |
29 | [SERVICE_EDIT]
30 |
31 | [SERVICE_DEL]
32 |
33 | [SERVICE_DISABLE]
34 |
35 | [SERVICE_ENABLE]
36 | }
37 |
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_add.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 添加
3 | * @param $param
4 | * @return bool
5 | */
6 | public function createData($param): bool
7 | {
8 | $result = $this->model::create($param);
9 | return (bool)$result;
10 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_del.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 删除
3 | * @param mixed $id
4 | * @return bool
5 | * @throws ApiServiceException
6 | */
7 | public function deleteData($id): bool
8 | {
9 | $result = $this->model::destroy(function ($query) use ($id) {
10 | $query->whereIn('id', $id);
11 | });
12 |
13 | if (!$result) {
14 | throw new ApiServiceException('更新失败');
15 | }
16 |
17 | return true;
18 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_disable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 禁用
3 | * @param mixed $id
4 | * @return bool
5 | * @throws ApiServiceException
6 | */
7 | public function disableData($id): bool
8 | {
9 | $result = $this->model
10 | ->whereIn('id', $id)
11 | ->save(['status' => 0]);
12 |
13 | if (!$result) {
14 | throw new ApiServiceException('禁用失败');
15 | }
16 |
17 | return true;
18 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_edit.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 修改
3 | * @param $id
4 | * @param $param
5 | * @return bool
6 | * @throws ApiServiceException
7 | */
8 | public function updateData($id, $param): bool
9 | {
10 | $data = $this->model->where('id', '=', $id)->findOrEmpty();
11 | if ($data->isEmpty()) {
12 | throw new ApiServiceException('数据不存在');
13 | }
14 | $result = $data->save($param);
15 |
16 | if (!$result) {
17 | throw new ApiServiceException('更新失败');
18 | }
19 |
20 | return true;
21 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_enable.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 启用
3 | * @param mixed $id
4 | * @return bool
5 | * @throws ApiServiceException
6 | */
7 | public function enableData($id): bool
8 | {
9 | $result = $this->model
10 | ->whereIn('id', $id)
11 | ->save(['status' => 1]);
12 |
13 | if (!$result) {
14 | throw new ApiServiceException('启用失败');
15 | }
16 | return true;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_index.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 列表
3 | * @param $param
4 | * @param $page
5 | * @param $limit
6 | * @return array
7 | * @throws ApiServiceException
8 | */
9 | public function getList($param, $page, $limit): array
10 | {
11 | try {
12 | $field = '[FIELD_LIST]';
13 | $data = $this->model
14 | ->scope('ApiWhere', $param)
15 | ->page($page, $limit)
16 | ->field($field)
17 | ->select()
18 | ->toArray();
19 | } catch (DataNotFoundException | ModelNotFoundException $e) {
20 | $data = [];
21 | } catch (DbException $e) {
22 | throw new ApiServiceException('查询列表失败,信息' . $e->getMessage());
23 | }
24 |
25 | return $data;
26 | }
--------------------------------------------------------------------------------
/extend/generate/stub/api_service/api_info.stub:
--------------------------------------------------------------------------------
1 | /**
2 | * 数据详情
3 | * @param $id
4 | * @return array
5 | * @throws ApiServiceException
6 | */
7 | public function getDataInfo($id): array
8 | {
9 | $data = $this->model->where('id', '=', $id)->findOrEmpty();
10 | if ($data->isEmpty()) {
11 | throw new ApiServiceException('数据不存在');
12 | }
13 | return $data->toArray();
14 | }
--------------------------------------------------------------------------------
/extend/generate/stub/model/Model.stub:
--------------------------------------------------------------------------------
1 | [RELATION_TYPE]([CLASS_NAME]::class);
7 | }
--------------------------------------------------------------------------------
/extend/generate/stub/validate/Validate.stub:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Color16 extends Rule
12 | {
13 | protected string $name = 'color16';
14 |
15 | protected string $msg = '必须为十六进制颜色代码';
16 | }
17 |
--------------------------------------------------------------------------------
/extend/generate/validate/ComplexPassword.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class ComplexPassword extends Rule
12 | {
13 | protected string $name = 'complexPassword';
14 | protected string $msg = '至少1个大写字母和1个小写字母和1个数字和1个特殊字符,8-16位';
15 | }
--------------------------------------------------------------------------------
/extend/generate/validate/Email.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Email extends Rule
12 | {
13 | protected string $name = 'email';
14 | protected string $msg = '必须为邮箱地址';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/IdCard.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class IdCard extends Rule
12 | {
13 | protected string $name = 'idCard';
14 | protected string $msg = '必须为身份证号码';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/Ip.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Ip extends Rule
12 | {
13 | protected string $name = 'ip';
14 | protected string $msg = '必须为IP地址';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/Ipv4.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | declare (strict_types=1);
7 |
8 | namespace generate\validate;
9 |
10 | class Ipv4 extends Rule
11 | {
12 | protected string $name = 'ipv4';
13 | protected string $msg = '必须为IPV4地址';
14 | }
15 |
--------------------------------------------------------------------------------
/extend/generate/validate/Ipv6.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Ipv6 extends Rule
12 | {
13 | protected string $name = 'ipv6';
14 | protected string $msg = '必须为IPV6地址';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/MiddlePassword.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class MiddlePassword extends Rule
12 | {
13 | protected string $name = 'middlePassword';
14 | protected string $msg = '至少1个大写字母和1个小写字母和1个数字,8-16位';
15 | }
--------------------------------------------------------------------------------
/extend/generate/validate/Mobile.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Mobile extends Rule
12 | {
13 | protected string $name = 'mobile';
14 | protected string $msg = '必须为11位手机号码';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/Number.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Number extends Rule
12 | {
13 | protected string $name = 'number';
14 | protected string $msg = '必须为纯数字';
15 | }
16 |
--------------------------------------------------------------------------------
/extend/generate/validate/Number6.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Number6 extends Rule
12 | {
13 | protected string $name = 'number6';
14 |
15 | protected string $msg = '必须为6位数字';
16 | }
17 |
--------------------------------------------------------------------------------
/extend/generate/validate/Required.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace generate\validate;
10 |
11 | class Required extends Rule
12 | {
13 |
14 | protected string $name = 'required';
15 | protected string $msg = '不能为空';
16 | }
17 |
--------------------------------------------------------------------------------
/extend/generate/validate/SimplePassword.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | declare (strict_types=1);
7 |
8 | namespace generate\validate;
9 |
10 | class SimplePassword extends Rule
11 | {
12 | protected string $name = 'simplePassword';
13 | protected string $msg = '至少1个字母和1个数字,6-16位';
14 | }
--------------------------------------------------------------------------------
/extend/generate/validate/Url.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 | declare (strict_types=1);
7 |
8 | namespace generate\validate;
9 |
10 | class Url extends Rule
11 | {
12 | protected string $name = 'url';
13 | protected string $msg = '必须为正确的网址';
14 | }
15 |
--------------------------------------------------------------------------------
/extend/util/jwt/JwtException.php:
--------------------------------------------------------------------------------
1 |
5 | */
6 |
7 | declare (strict_types=1);
8 |
9 | namespace util\jwt;
10 |
11 | use Exception;
12 |
13 | class JwtException extends Exception
14 | {
15 |
16 | }
--------------------------------------------------------------------------------
/extend/util/jwt/README.md:
--------------------------------------------------------------------------------
1 | # JWT加密验证
2 |
3 | > 简单的jwt加密验证扩展
4 |
5 | ## 使用方法
6 |
7 | ### HS256(HS384,HS512)加密
8 |
9 | ```php
10 |
11 | $key = 'ThisIsKey';
12 | $jwt =new \util\jwt\Jwt();
13 | $token = $jwt->setAlg('HS256')
14 | ->setKey($key)
15 | ->setClaim()
16 | ->getToken();
17 |
18 | ```
19 |
20 | ### HS256(HS384,HS512)验证
21 |
22 | ```php
23 | $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3MiLCJhdWQiOiJhdWQiLCJqdGkiOiI2YjkxNTE3YmZkMzM5YmI4ZDI5MmJiOGM1NmYzZDVkOSIsImlhdCI6MTYzNjM0MTQ3NywibmJmIjoxNjM2MzQxNDc3LCJleHAiOjE2MzYzNDg2NzcsInVpZCI6MX0.352KUpUo08S6ujeSCyVhwYgA9l5XMU9drremhFE5KKM';
24 | $key = 'ThisIsKey';
25 | $jwt =new \util\jwt\Jwt();
26 | $result = $jwt->setAlg('HS256')->setKey($key)->checkToken($token);
27 | if($result===true){
28 | $uid = $jwt->getUid();
29 | }else{
30 | var_dump($jwt->getMessage());
31 | }
32 | ```
33 |
34 | ### RS256(RS384,RS512)加密
35 | ```php
36 | $private_key = 'ThisIsKey';
37 | $jwt =new \util\jwt\Jwt();
38 | $token = $jwt->setAlg('RS256')
39 | ->setPrivateKey($private_key)
40 | ->setClaim()
41 | ->getToken();
42 | ```
43 | ### RS256(RS384,RS512)验证
44 | ```php
45 | $public_key = 'ThisIsKey';
46 | $jwt =new \util\jwt\Jwt();
47 | $token = $jwt->setAlg('RS256')
48 | ->setPublicKey($key)
49 | ->setClaim()
50 | ->getToken();
51 | ```
52 |
53 | 具体示例代码可参考Example.php文件内方法。
--------------------------------------------------------------------------------
/extend/util/jwt/private.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtGJrW/kUyp8AS
3 | UhAm/c928vRlO8Ie0CV+/T0PkD0mbEHyaU8ikClUXI1MBpDaCOtSC40y2izCZ1uU
4 | JvUPuJ8nzKwIwtgEGmdj8k2hJy0QzR8Swk2jhzxd+xT8oaOWdUXD4rZsATxLqNXm
5 | 2cbykWRSWdyiquOfFjfh3pAak9cs3zhXeL21wiJtLJdcimQjpaltPZDB0WWOi5Eg
6 | pMo/Dc9FIn7r+Oq6Yop7ShhrVGxji36GiAUvay3lVOpCRPrA2ql8jdgmWpXehMGA
7 | WBNTfOK5UFmI/PA+frhEy0mU7CrjVR96Hm/egbROkXJemB+gxpwwwAPGMpsiWq45
8 | qAOrXCgjAgMBAAECggEAAz2hsILEMuWXIACvUruPxc9YqgiLYt5MxWriWMc/jdeb
9 | CHnWRHRkgbLV5mV9Esf19+xFcX1KNz2OJmDwV6ICQNGBKwzS1IjWBLYFpA3CtzzP
10 | 5x8CKxyeEbhgtTYlhOyfKMK23aDMSzJXBuJu6h20viH2kokWh+T3mN/83LKF5c4k
11 | MtNsQvXKrUI53M6qWfx+ZnmhUuM+LAX/Mq0WhJMEf6Af8uB44Elf4A3MEOdqhhyn
12 | BPo/a8kNFKshgf//FvjLY7agnQ/uEdvAicQEAh1OhIp8cdr07jgchsTRM+eOWqCL
13 | 12pMIOVVybvkwQqGldYPOek1cGASEjM1SHc77Rs98QKBgQDVXIRbGQrEkSvOMTML
14 | LKn8lTToJn1h36O5JqXB6ngRWiXLgF9GpnWSyp0U8qXeXd4D6ZExHP7G1/Ny44lt
15 | KNBYaJAN1VlqqvVMA70MoEbyuFLREGTMa+MXAPpfs5Ue+kixYIEj9rkeiZDQDusc
16 | pD5RLkTcOMDBrRByfAuEkgyHiwKBgQDPsCHZqkRGEGRIA8xcYCtfcgDFtUoyJ3a3
17 | FG8H+805gbP5hc0EhPSnRlacrL2yNxabB4XfH3gdQKlo8lgDe0W0E1ynHwbGQ6mq
18 | KhPgEx5wI9UPY6WJmg7aCij3FSH/j/sD6S5lUazm6mpP6ZfO9bivKZ1MXBmAhYFs
19 | ARo5V6i0yQKBgQCYeAm5U9bnC1rDeVMhrCQ5dKKfN0ooU/maySxwu85bkBEsMKtl
20 | QHUKljHUk2XG10tdfl6cOz0x+YZmVoWRdTYVx3sR96FzYYHzdUR2rl6k+uVrswxl
21 | LL/WY4OIOjvZLEAgSXdfrOMzGFlc5RxMlm5V8vuQaBoPDU6QkWZlsTy06wKBgEs1
22 | CMz9b0O/49CAL5yz5oDlk4oEoB2RVNfvOlW1xRcx9K5C2X7tdnqsaejKVNcYQ8NX
23 | 8g5eIuzU4YPzXhPEq/UNnduWzKk3D1Vjb1cRFVCeaSTtfKBbfU1PqI3wxSL6THea
24 | FQbzkJz9/gl6GVMEgCBN/XwNTd7QeZFWxNxG9fyhAoGARYj8aXtMzUefSblVJGvq
25 | FGNfu6M8/ddKZGV3iFApPHozrJW5zeCHuOUfdWljIq73yvd3TY0+YJH4csDQjCNH
26 | 9mIf/iflCkbR3PnmwrYJziUrEr0if8pHk/MgPWjFS7V+J9C+JTRBWspvXIcDljmD
27 | t1cZfREnNoEV5Rpwb1bC4iY=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/extend/util/jwt/public.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArRia1v5FMqfAElIQJv3P
3 | dvL0ZTvCHtAlfv09D5A9JmxB8mlPIpApVFyNTAaQ2gjrUguNMtoswmdblCb1D7if
4 | J8ysCMLYBBpnY/JNoSctEM0fEsJNo4c8XfsU/KGjlnVFw+K2bAE8S6jV5tnG8pFk
5 | UlncoqrjnxY34d6QGpPXLN84V3i9tcIibSyXXIpkI6WpbT2QwdFljouRIKTKPw3P
6 | RSJ+6/jqumKKe0oYa1RsY4t+hogFL2st5VTqQkT6wNqpfI3YJlqV3oTBgFgTU3zi
7 | uVBZiPzwPn64RMtJlOwq41Ufeh5v3oG0TpFyXpgfoMacMMADxjKbIlquOagDq1wo
8 | IwIDAQAB
9 | -----END PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 |
2 | Options +FollowSymlinks -Multiviews
3 | RewriteEngine On
4 |
5 | RewriteCond %{REQUEST_FILENAME} !-d
6 | RewriteCond %{REQUEST_FILENAME} !-f
7 | RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
8 |
9 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 |
12 | // [ 应用入口文件 ]
13 | namespace think;
14 |
15 | require __DIR__ . '/../vendor/autoload.php';
16 |
17 | // 执行HTTP应用并响应
18 | $http = (new App())->http;
19 |
20 | $response = $http->run();
21 |
22 | $response->send();
23 |
24 | $http->end($response);
25 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:/admin/
3 | Disallow:/api/
4 |
--------------------------------------------------------------------------------
/public/router.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | // $Id$
12 |
13 | if (is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])) {
14 | return false;
15 | }
16 |
17 | $_SERVER['SCRIPT_FILENAME'] = __DIR__ . '/index.php';
18 |
19 | require __DIR__ . '/index.php';
20 |
--------------------------------------------------------------------------------
/public/static/admin/css/access.css:
--------------------------------------------------------------------------------
1 | .checkbox {
2 | cursor: pointer;
3 | }
4 |
5 | .checkMod {
6 | margin-bottom: 20px;
7 | border: 1px solid #ebebeb;
8 | padding-bottom: 5px;
9 | }
10 |
11 | .checkMod dt {
12 | padding-left: 10px;
13 | height: 30px;
14 | line-height: 30px;
15 | font-weight: bold;
16 | border-bottom: 1px solid #ebebeb;
17 | background-color: #ECECEC;
18 | }
19 |
20 | .checkMod dt {
21 | margin-bottom: 5px;
22 | border-bottom-color: #ebebeb;
23 | background-color: #ECECEC;
24 | }
25 |
26 | .checkbox, .radio {
27 | display: inline-block;
28 | height: 20px;
29 | line-height: 20px;
30 | margin-left: 20px;
31 | margin-right: 20px;
32 | }
33 |
34 | .checkMod dd {
35 | padding-left: 30px;
36 | line-height: 30px;
37 | }
38 |
39 | .checkMod dd .checkbox {
40 | margin: 0 30px 0 0;
41 | font-weight: normal;
42 | }
43 |
44 | .checkMod dd .divsion {
45 | margin-right: 20px;
46 | }
47 |
48 | .checkMod dt {
49 | line-height: 30px;
50 | font-weight: bold;
51 |
52 | }
53 |
54 | .rule_check {
55 | border: 1px solid #ebebeb;
56 | margin: auto;
57 | padding: 5px 15px;
58 | }
59 |
60 | .menu_parent {
61 | margin-bottom: 5px;
62 | }
--------------------------------------------------------------------------------
/public/static/admin/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/images/avatar.png
--------------------------------------------------------------------------------
/public/static/admin/images/login-default-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/images/login-default-bg.jpg
--------------------------------------------------------------------------------
/public/static/admin/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/images/logo.png
--------------------------------------------------------------------------------
/public/static/admin/js/requrest.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/js/requrest.js
--------------------------------------------------------------------------------
/public/static/admin/plugins/bootstrap-number/bootstrap-number.min.js:
--------------------------------------------------------------------------------
1 | !function(a){a.fn.bootstrapNumber=function(b){var c=a.extend({upClass:"default",downClass:"default",upText:"+",downText:"-",center:!0},b);return this.each(function(){function i(a){return isNaN(a)||f&&f>a||g&&a>g?!1:(e.focus().val(a),e.trigger("change"),!0)}var d=a(this),e=d.clone(!0,!0),f=d.attr("min"),g=d.attr("max"),h=parseInt(d.attr("step"))||1,j=a("
"),k=a(""+c.downText+" ").attr("class","btn btn-"+c.downClass).click(function(){i(parseInt(e.val()||e.attr("value"))-h)}),l=a(""+c.upText+" ").attr("class","btn btn-"+c.upClass).click(function(){i(parseInt(e.val()||e.attr("value"))+h)});a(" ").append(k).appendTo(j),e.appendTo(j),e&&c.center&&e.css("text-align","center"),a(" ").append(l).appendTo(j),e.prop("type","text").keydown(function(b){var c,d;-1!==a.inArray(b.keyCode,[46,8,9,27,13,110,190])||65==b.keyCode&&b.ctrlKey===!0||b.keyCode>=35&&b.keyCode<=39||((b.shiftKey||b.keyCode<48||b.keyCode>57)&&(b.keyCode<96||b.keyCode>105)&&b.preventDefault(),c=String.fromCharCode(b.which),d=parseInt(e.val()+c),(f&&f>d||g&&d>g)&&b.preventDefault())}),d.replaceWith(j)})}}(jQuery);
--------------------------------------------------------------------------------
/public/static/admin/plugins/fileinput/img/loading-sm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/plugins/fileinput/img/loading-sm.gif
--------------------------------------------------------------------------------
/public/static/admin/plugins/fileinput/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/plugins/fileinput/img/loading.gif
--------------------------------------------------------------------------------
/public/static/admin/plugins/fileinput/themes/explorer/theme.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * bootstrap-fileinput v5.2.7
3 | * http://plugins.krajee.com/file-input
4 | *
5 | * Krajee Explorer theme configuration for bootstrap-fileinput. Load this theme file after loading `fileinput.js`.
6 | *
7 | * Author: Kartik Visweswaran
8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com
9 | *
10 | * Licensed under the BSD-3-Clause
11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
12 | */!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(e){"use strict";e.fn.fileinputThemes.explorer={layoutTemplates:{footer:'{caption}
{size}{progress}
{indicator} {actions}
',actions:'{drag}\n\n \n
'},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame"}});
--------------------------------------------------------------------------------
/public/static/admin/plugins/fileinput/themes/fa/theme.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * bootstrap-fileinput v5.2.7
3 | * http://plugins.krajee.com/file-input
4 | *
5 | * Font Awesome icon theme configuration for bootstrap-fileinput. Requires font awesome assets to be loaded.
6 | *
7 | * Author: Kartik Visweswaran
8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com
9 | *
10 | * Licensed under the BSD-3-Clause
11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
12 | */!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(a){"use strict";a.fn.fileinputThemes.fa={fileActionSettings:{removeIcon:' ',uploadIcon:' ',uploadRetryIcon:' ',downloadIcon:' ',zoomIcon:' ',dragIcon:' ',indicatorNew:' ',indicatorSuccess:' ',indicatorError:' ',indicatorLoading:' ',indicatorPaused:' '},layoutTemplates:{fileIcon:' '},previewZoomButtonIcons:{prev:' ',next:' ',toggleheader:' ',fullscreen:' ',borderless:' ',close:' '},previewFileIcon:' ',browseIcon:' ',removeIcon:' ',cancelIcon:' ',pauseIcon:' ',uploadIcon:' ',msgValidationErrorIcon:' '}});
--------------------------------------------------------------------------------
/public/static/admin/plugins/fontawesome-free/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/plugins/fontawesome-free/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/public/static/admin/plugins/fontawesome-free/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/plugins/fontawesome-free/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/public/static/admin/plugins/fontawesome-free/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yupoxiong/BearAdmin/a1a6261d549e8d7e246fcd76fe1be0c1f8c4bfe6/public/static/admin/plugins/fontawesome-free/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/public/static/admin/plugins/icheck-bootstrap/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Hovhannes Bantikyan
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 |
--------------------------------------------------------------------------------
/public/static/admin/plugins/jquery-validation/localization/messages_zh.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
2 | * https://jqueryvalidation.org/
3 | * Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"这是必填字段",remote:"请修正此字段",email:"请输入有效的电子邮件地址",url:"请输入有效的网址",date:"请输入有效的日期",dateISO:"请输入有效的日期 (YYYY-MM-DD)",number:"请输入有效的数字",digits:"只能输入数字",creditcard:"请输入有效的信用卡号码",equalTo:"你的输入不相同",extension:"请输入有效的后缀",maxlength:a.validator.format("最多可以输入 {0} 个字符"),minlength:a.validator.format("最少要输入 {0} 个字符"),rangelength:a.validator.format("请输入长度在 {0} 到 {1} 之间的字符串"),range:a.validator.format("请输入范围在 {0} 到 {1} 之间的数值"),step:a.validator.format("请输入 {0} 的整数倍值"),max:a.validator.format("请输入不大于 {0} 的数值"),min:a.validator.format("请输入不小于 {0} 的数值")}),a});
--------------------------------------------------------------------------------
/public/static/admin/plugins/jquery-validation/localization/messages_zh_TW.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery Validation Plugin - v1.19.3 - 1/9/2021
2 | * https://jqueryvalidation.org/
3 | * Copyright (c) 2021 Jörn Zaefferer; Licensed MIT */
4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","../jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return a.extend(a.validator.messages,{required:"必須填寫",remote:"請修正此欄位",email:"請輸入有效的電子郵件",url:"請輸入有效的網址",date:"請輸入有效的日期",dateISO:"請輸入有效的日期 (YYYY-MM-DD)",number:"請輸入正確的數值",digits:"只可輸入數字",creditcard:"請輸入有效的信用卡號碼",equalTo:"請重複輸入一次",extension:"請輸入有效的後綴",maxlength:a.validator.format("最多 {0} 個字"),minlength:a.validator.format("最少 {0} 個字"),rangelength:a.validator.format("請輸入長度為 {0} 至 {1} 之間的字串"),range:a.validator.format("請輸入 {0} 至 {1} 之間的數值"),step:a.validator.format("請輸入 {0} 的整數倍值"),max:a.validator.format("請輸入不大於 {0} 的數值"),min:a.validator.format("請輸入不小於 {0} 的數值")}),a});
--------------------------------------------------------------------------------
/public/static/admin/plugins/jquery-viewer/jquery-viewer.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Viewer v1.0.1
3 | * https://fengyuanchen.github.io/jquery-viewer
4 | *
5 | * Copyright 2018-present Chen Fengyuan
6 | * Released under the MIT license
7 | *
8 | * Date: 2019-12-14T09:00:02.315Z
9 | */
10 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("jquery"),require("viewerjs")):"function"==typeof define&&define.amd?define(["jquery","viewerjs"],t):t((e=e||self).jQuery,e.Viewer)}(this,function(d,v){"use strict";if(d=d&&d.hasOwnProperty("default")?d.default:d,v=v&&v.hasOwnProperty("default")?v.default:v,d&&d.fn&&v){var e=d.fn.viewer,w="viewer";d.fn.viewer=function(o){for(var e=arguments.length,u=new Array(11){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(r+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(n+"")).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u
10 | // +----------------------------------------------------------------------
11 | use think\facade\Route;
12 |
--------------------------------------------------------------------------------
/think:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | console->run();
--------------------------------------------------------------------------------