├── backend ├── public │ ├── favicon.ico │ ├── robots.txt │ ├── img │ │ └── 1.jpg │ └── .htaccess ├── storage │ ├── logs │ │ └── .gitignore │ ├── debugbar │ │ └── .gitignore │ ├── app │ │ ├── public │ │ │ └── .gitignore │ │ └── .gitignore │ └── framework │ │ ├── sessions │ │ └── .gitignore │ │ ├── testing │ │ └── .gitignore │ │ ├── views │ │ └── .gitignore │ │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ │ └── .gitignore ├── bootstrap │ ├── cache │ │ └── .gitignore │ └── app.php ├── database │ ├── .gitignore │ ├── seeds │ │ ├── DatabaseSeeder.php │ │ └── UsersTableSeeder.php │ ├── migrations │ │ ├── 2019_06_07_014457_create_table_admin_user_has_roles.php │ │ ├── 2019_06_07_014208_create_table_admin_roles.php │ │ ├── 2019_06_07_014412_create_table_admin_role_has_permission.php │ │ ├── 2019_06_19_004447_create_table_admin_request_log.php │ │ └── 2019_06_04_000000_create_table_admin_users.php │ └── factories │ │ └── UserFactory.php ├── resources │ ├── js │ │ ├── router │ │ │ ├── _import_production.js │ │ │ └── _import_development.js │ │ ├── views │ │ │ ├── permission │ │ │ │ └── create.vue │ │ │ ├── deposit │ │ │ │ └── index.vue │ │ │ ├── withdrawal │ │ │ │ └── index.vue │ │ │ ├── common │ │ │ │ └── SubPage.vue │ │ │ ├── notices │ │ │ │ ├── edit.vue │ │ │ │ └── create.vue │ │ │ ├── app.vue │ │ │ └── default │ │ │ │ └── index.vue │ │ ├── icons │ │ │ ├── svg │ │ │ │ ├── chart.svg │ │ │ │ ├── size.svg │ │ │ │ ├── link.svg │ │ │ │ ├── component.svg │ │ │ │ ├── guide.svg │ │ │ │ ├── money.svg │ │ │ │ ├── email.svg │ │ │ │ ├── drag.svg │ │ │ │ ├── documentation.svg │ │ │ │ ├── fullscreen.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── user.svg │ │ │ │ ├── excel.svg │ │ │ │ ├── example.svg │ │ │ │ ├── star.svg │ │ │ │ ├── table.svg │ │ │ │ ├── search.svg │ │ │ │ ├── password.svg │ │ │ │ ├── education.svg │ │ │ │ ├── tab.svg │ │ │ │ ├── message.svg │ │ │ │ ├── theme.svg │ │ │ │ ├── peoples.svg │ │ │ │ ├── edit.svg │ │ │ │ ├── nested.svg │ │ │ │ ├── tree-table.svg │ │ │ │ ├── eye.svg │ │ │ │ ├── clipboard.svg │ │ │ │ ├── list.svg │ │ │ │ ├── users.svg │ │ │ │ ├── icon.svg │ │ │ │ ├── permission.svg │ │ │ │ ├── international.svg │ │ │ │ ├── config.svg │ │ │ │ ├── wechat.svg │ │ │ │ ├── skill.svg │ │ │ │ ├── people.svg │ │ │ │ ├── notice.svg │ │ │ │ ├── language.svg │ │ │ │ ├── eye-open.svg │ │ │ │ ├── withdrawal.svg │ │ │ │ ├── wechat_login.svg │ │ │ │ ├── 404.svg │ │ │ │ ├── zip.svg │ │ │ │ ├── bug.svg │ │ │ │ ├── pdf.svg │ │ │ │ ├── exit-fullscreen.svg │ │ │ │ └── tree.svg │ │ │ ├── index.js │ │ │ └── svgo.yml │ │ ├── api │ │ │ ├── orders.js │ │ │ ├── log.js │ │ │ ├── role.js │ │ │ ├── notice.js │ │ │ ├── auth.js │ │ │ ├── users.js │ │ │ ├── client.js │ │ │ ├── permission.js │ │ │ ├── usergroup.js │ │ │ ├── config.js │ │ │ └── admin.js │ │ ├── layout │ │ │ ├── components │ │ │ │ ├── index.js │ │ │ │ ├── Sidebar │ │ │ │ │ ├── Item.vue │ │ │ │ │ ├── Link.vue │ │ │ │ │ └── FixiOSBug.js │ │ │ │ └── AppMain.vue │ │ │ └── mixin │ │ │ │ └── ResizeHandler.js │ │ ├── directive │ │ │ └── permission │ │ │ │ ├── index.js │ │ │ │ └── permission.js │ │ ├── utils │ │ │ └── validate.js │ │ ├── store │ │ │ ├── getters.js │ │ │ ├── modules │ │ │ │ ├── settings.js │ │ │ │ ├── permission.js │ │ │ │ └── app.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── Tinymce │ │ │ │ ├── toolbar.js │ │ │ │ ├── plugins.js │ │ │ │ └── dynamicLoadScript.js │ │ │ ├── Screenfull │ │ │ │ └── index.vue │ │ │ └── Hamburger │ │ │ │ └── index.vue │ │ ├── bootstrap.js │ │ └── settings.js │ ├── sass │ │ ├── app.scss │ │ ├── variables.scss │ │ ├── element-variables.scss │ │ ├── transition.scss │ │ ├── element-ui.scss │ │ └── mixin.scss │ ├── lang │ │ ├── zh_cn │ │ │ └── auth.php │ │ └── en │ │ │ ├── pagination.php │ │ │ ├── auth.php │ │ │ └── passwords.php │ └── views │ │ ├── auth │ │ └── verify.blade.php │ │ ├── index.blade.php │ │ └── wechat.blade.php ├── tests │ ├── TestCase.php │ ├── Unit │ │ └── ExampleTest.php │ ├── Feature │ │ └── ExampleTest.php │ └── CreatesApplication.php ├── .styleci.yml ├── .gitignore ├── .babelrc ├── app │ ├── Http │ │ ├── Middleware │ │ │ ├── EncryptCookies.php │ │ │ ├── CheckForMaintenanceMode.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustProxies.php │ │ │ ├── VerifyCsrfToken.php │ │ │ └── RedirectIfAuthenticated.php │ │ ├── Controllers │ │ │ ├── HomeController.php │ │ │ ├── Controller.php │ │ │ ├── Auth │ │ │ │ ├── ForgotPasswordController.php │ │ │ │ ├── ResetPasswordController.php │ │ │ │ └── VerificationController.php │ │ │ └── OrdersController.php │ │ └── Requests │ │ │ ├── CommonIndexRequest.php │ │ │ └── ClientCreateRequest.php │ ├── Providers │ │ ├── BroadcastServiceProvider.php │ │ ├── AppServiceProvider.php │ │ ├── EventServiceProvider.php │ │ └── AuthServiceProvider.php │ ├── Console │ │ └── Kernel.php │ ├── Helpers │ │ └── function.php │ ├── Events │ │ └── NotifyEvent.php │ └── Jobs │ │ └── RefreshConfig.php ├── routes │ ├── api.php │ ├── console.php │ ├── channels.php │ └── web.php ├── server.php ├── laravel-echo-server.json ├── .env.example ├── config │ ├── view.php │ ├── services.php │ ├── hashing.php │ └── broadcasting.php ├── phpunit.xml └── artisan ├── frontend-api ├── public │ ├── favicon.ico │ ├── robots.txt │ └── .htaccess ├── storage │ ├── logs │ │ └── .gitignore │ ├── app │ │ ├── public │ │ │ └── .gitignore │ │ └── .gitignore │ └── framework │ │ ├── sessions │ │ └── .gitignore │ │ ├── testing │ │ └── .gitignore │ │ ├── views │ │ └── .gitignore │ │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ │ └── .gitignore ├── bootstrap │ ├── cache │ │ └── .gitignore │ └── app.php ├── database │ ├── .gitignore │ ├── seeds │ │ └── DatabaseSeeder.php │ ├── migrations │ │ ├── 2014_10_12_100000_create_password_resets_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ └── 2014_10_12_000000_create_users_table.php │ └── factories │ │ └── UserFactory.php ├── .gitattributes ├── .gitignore ├── tests │ ├── TestCase.php │ ├── Unit │ │ └── ExampleTest.php │ ├── Feature │ │ └── ExampleTest.php │ └── CreatesApplication.php ├── .editorconfig ├── app │ ├── Http │ │ ├── Middleware │ │ │ ├── EncryptCookies.php │ │ │ ├── CheckForMaintenanceMode.php │ │ │ ├── TrimStrings.php │ │ │ ├── TrustProxies.php │ │ │ ├── Authenticate.php │ │ │ ├── VerifyCsrfToken.php │ │ │ ├── RedirectIfAuthenticated.php │ │ │ └── EnableCrossRequestMiddleware.php │ │ └── Controllers │ │ │ ├── TestController.php │ │ │ ├── PaymentController.php │ │ │ ├── UserController.php │ │ │ ├── Controller.php │ │ │ └── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── ResetPasswordController.php │ │ │ └── VerificationController.php │ ├── Providers │ │ ├── BroadcastServiceProvider.php │ │ ├── AppServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ └── EventServiceProvider.php │ └── Console │ │ └── Kernel.php ├── resources │ ├── lang │ │ ├── zh_cn │ │ │ └── auth.php │ │ └── en │ │ │ ├── pagination.php │ │ │ ├── auth.php │ │ │ └── passwords.php │ └── views │ │ └── index.blade.php ├── routes │ ├── web.php │ ├── channels.php │ ├── api.php │ └── console.php ├── server.php ├── .env.example ├── config │ ├── services.php │ ├── view.php │ ├── hashing.php │ └── broadcasting.php └── phpunit.xml ├── frontend-web ├── .env ├── public │ ├── favicon.ico │ ├── img │ │ ├── index-bg.jpg │ │ ├── ico │ │ │ ├── ico-lock.png │ │ │ ├── ico-user.png │ │ │ └── loginbico.png │ │ └── m │ │ │ └── login_bg_s.jpg │ └── index.html ├── src │ ├── assets │ │ ├── logo.png │ │ └── css │ │ │ └── reset.css │ ├── store │ │ ├── getters.js │ │ └── index.js │ ├── api │ │ ├── test.js │ │ └── user.js │ ├── views-web │ │ ├── App.vue │ │ └── index │ │ │ └── Index.vue │ ├── main-web.js │ ├── main-h5.js │ └── views-h5 │ │ ├── App.vue │ │ └── index │ │ └── Index.vue ├── .gitignore ├── README.md ├── babel.config.js └── package.json ├── doc └── images │ └── index.png ├── .gitattributes ├── common └── Models │ ├── Clients.php │ ├── Config.php │ ├── UserGroup.php │ ├── AdminUserHasRole.php │ ├── Orders.php │ ├── Notices.php │ ├── AdminRoleHasPermission.php │ ├── AdminLoginLog.php │ ├── AdminRequestLog.php │ ├── AdminRolePermissions.php │ ├── Users.php │ └── AdminRoles.php └── .editorconfig /backend/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /backend/storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | -------------------------------------------------------------------------------- /backend/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /backend/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /backend/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | *.sqlite-journal 3 | -------------------------------------------------------------------------------- /frontend-api/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /backend/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-web/.env: -------------------------------------------------------------------------------- 1 | VUE_APP_DOMAIN=http://frontend-api.laravel_admin.me 2 | -------------------------------------------------------------------------------- /backend/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /doc/images/index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/doc/images/index.png -------------------------------------------------------------------------------- /backend/public/img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/backend/public/img/1.jpg -------------------------------------------------------------------------------- /backend/resources/js/router/_import_production.js: -------------------------------------------------------------------------------- 1 | module.exports = file => () => import('@/views/' + file + '.vue') -------------------------------------------------------------------------------- /frontend-web/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/favicon.ico -------------------------------------------------------------------------------- /frontend-web/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/src/assets/logo.png -------------------------------------------------------------------------------- /frontend-web/public/img/index-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/img/index-bg.jpg -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /frontend-web/public/img/ico/ico-lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/img/ico/ico-lock.png -------------------------------------------------------------------------------- /frontend-web/public/img/ico/ico-user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/img/ico/ico-user.png -------------------------------------------------------------------------------- /frontend-web/public/img/ico/loginbico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/img/ico/loginbico.png -------------------------------------------------------------------------------- /frontend-web/public/img/m/login_bg_s.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auroraruanjian/laravel-admin/HEAD/frontend-web/public/img/m/login_bg_s.jpg -------------------------------------------------------------------------------- /backend/resources/js/router/_import_development.js: -------------------------------------------------------------------------------- 1 | module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+ -------------------------------------------------------------------------------- /frontend-api/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /backend/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /frontend-api/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /frontend-web/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | username: state => state.user.username, 3 | nickname: state => state.user.nickname, 4 | } 5 | 6 | export default getters 7 | -------------------------------------------------------------------------------- /frontend-web/src/api/test.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getTest() { 4 | return fetch({ 5 | url: 'test', 6 | method: 'get', 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /backend/resources/js/views/permission/create.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/chart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/sass/app.scss: -------------------------------------------------------------------------------- 1 | // Fonts 2 | //@import url('https://fonts.googleapis.com/css?family=Nunito'); 3 | 4 | // Variables 5 | @import 'variables'; 6 | 7 | // Bootstrap 8 | //@import '~bootstrap/scss/bootstrap'; 9 | -------------------------------------------------------------------------------- /common/Models/Clients.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /backend/resources/js/views/withdrawal/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /backend/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/views/common/SubPage.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /backend/.styleci.yml: -------------------------------------------------------------------------------- 1 | php: 2 | preset: laravel 3 | disabled: 4 | - unused_use 5 | finder: 6 | not-name: 7 | - index.php 8 | - server.php 9 | js: 10 | finder: 11 | not-name: 12 | - webpack.mix.js 13 | css: true 14 | -------------------------------------------------------------------------------- /common/Models/AdminUserHasRole.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as AppMain } from './AppMain' 2 | export { default as Navbar } from './Navbar' 3 | export { default as Settings } from './Settings' 4 | export { default as Sidebar } from './Sidebar/index.vue' 5 | export { default as TagsView } from './TagsView/index.vue' 6 | -------------------------------------------------------------------------------- /frontend-web/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /backend/resources/js/views/notices/edit.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/component.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/guide.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/views/notices/create.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /backend/database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /backend/resources/js/icons/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import SvgIcon from '@/components/SvgIcon'// svg component 3 | 4 | // register globally 5 | Vue.component('svg-icon', SvgIcon) 6 | 7 | const req = require.context('./svg', false, /\.svg$/) 8 | const requireAll = requireContext => requireContext.keys().map(requireContext) 9 | requireAll(req) 10 | -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /public/css 5 | /public/js 6 | /public/fonts 7 | /public/mix-manifest.json 8 | /storage/*.key 9 | /vendor 10 | .env 11 | .phpunit.result.cache 12 | Homestead.json 13 | Homestead.yaml 14 | npm-debug.log 15 | yarn-error.log 16 | /public/images 17 | /public/*.js 18 | laravel-echo-server.lock 19 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/money.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /backend/resources/js/directive/permission/index.js: -------------------------------------------------------------------------------- 1 | import permission from './permission' 2 | 3 | const install = function(Vue) { 4 | Vue.directive('permission', permission) 5 | } 6 | 7 | if (window.Vue) { 8 | window['permission'] = permission 9 | Vue.use(install); // eslint-disable-line 10 | } 11 | 12 | permission.install = install 13 | export default permission -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/email.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/database/seeds/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/drag.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svgo.yml: -------------------------------------------------------------------------------- 1 | # replace default config 2 | 3 | # multipass: true 4 | # full: true 5 | 6 | plugins: 7 | 8 | # - name 9 | # 10 | # or: 11 | # - name: false 12 | # - name: true 13 | # 14 | # or: 15 | # - name: 16 | # param1: 1 17 | # param2: 2 18 | 19 | - removeAttrs: 20 | attrs: 21 | - 'fill' 22 | - 'fill-rule' 23 | -------------------------------------------------------------------------------- /backend/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { "modules": false }],"@vue/babel-preset-jsx"], 3 | "plugins": [ 4 | [ 5 | "component", 6 | { 7 | "libraryName": "element-ui", 8 | "styleLibraryName": "theme-chalk" 9 | } 10 | ], 11 | "@babel/plugin-syntax-dynamic-import" 12 | ] 13 | } -------------------------------------------------------------------------------- /backend/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend-web/src/views-web/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 16 | -------------------------------------------------------------------------------- /backend/resources/js/views/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/TestController.php: -------------------------------------------------------------------------------- 1 | response(1,'1111'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/documentation.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-web/README.md: -------------------------------------------------------------------------------- 1 | # frontend-web 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Lints and fixes files 19 | ``` 20 | npm run lint 21 | ``` 22 | 23 | ### Customize configuration 24 | See [Configuration Reference](https://cli.vuejs.org/config/). 25 | -------------------------------------------------------------------------------- /backend/app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/user.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/CheckForMaintenanceMode.php: -------------------------------------------------------------------------------- 1 | '用户名', 5 | 'Password' => '密码', 6 | 'failed' => '对不起,用户名或密码错误!', 7 | 'throttle' => '登录太频繁,请稍等 :seconds 在试', 8 | 'logout' => '退出', 9 | 'logoutSuccess' => '退出成功!', 10 | 'permissions' => [ 11 | 'false' => '对不起,您没有权限!', 12 | ], 13 | 'login' => [ 14 | 'false' => '对不起,您还未登陆!', 15 | ] 16 | ]; -------------------------------------------------------------------------------- /frontend-api/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend-api/resources/lang/zh_cn/auth.php: -------------------------------------------------------------------------------- 1 | '用户名', 5 | 'Password' => '密码', 6 | 'failed' => '对不起,用户名或密码错误!', 7 | 'throttle' => '登录太频繁,请稍等 :seconds 在试', 8 | 'logout' => '退出', 9 | 'logoutSuccess' => '退出成功!', 10 | 'permissions' => [ 11 | 'false' => '对不起,您没有权限!', 12 | ], 13 | 'login' => [ 14 | 'false' => '对不起,您还未登陆!', 15 | ] 16 | ]; -------------------------------------------------------------------------------- /frontend-web/src/main-web.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import router from './router/web.js' 3 | import store from './store' 4 | 5 | window.router = router; 6 | 7 | import ElementUI from 'element-ui'; 8 | // import 'element-ui/lib/theme-chalk/index.css'; 9 | 10 | import App from './views-web/App.vue' 11 | 12 | Vue.use(ElementUI); 13 | 14 | Vue.config.productionTip = false 15 | 16 | new Vue({ 17 | router, 18 | store, 19 | render: h => h(App) 20 | }).$mount('#app') 21 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/excel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/utils/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by PanJiaChen on 16/11/18. 3 | */ 4 | 5 | /** 6 | * @param {string} path 7 | * @returns {Boolean} 8 | */ 9 | export function isExternal(path) { 10 | return /^(https?:|mailto:|tel:)/.test(path) 11 | } 12 | 13 | /** 14 | * @param {string} str 15 | * @returns {Boolean} 16 | */ 17 | export function validUsername(str) { 18 | const valid_map = ['admin', 'editor'] 19 | return valid_map.indexOf(str.trim()) >= 0 20 | } -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/PaymentController.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/Models/AdminRolePermissions.php: -------------------------------------------------------------------------------- 1 | belongsToMany( 15 | AdminRoles::class, 16 | 'admin_role_has_permission', 17 | 'permission_id', 18 | 'role_id' 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend-api/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /frontend-web/src/main-h5.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import router from './router/h5.js' 3 | import store from './store' 4 | import App from './views-h5/App.vue' 5 | 6 | window.router = router; 7 | 8 | import { Button,Checkbox,Icon,Dialog,Notify } from 'vant'; 9 | Vue.use(Button); 10 | Vue.use(Checkbox); 11 | Vue.use(Icon); 12 | Vue.use(Dialog); 13 | Vue.use(Notify); 14 | 15 | Vue.config.productionTip = false 16 | 17 | new Vue({ 18 | router, 19 | store, 20 | render: h => h(App) 21 | }).$mount('#app') 22 | -------------------------------------------------------------------------------- /backend/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | state.user.username, 3 | sidebar: state => state.app.sidebar, 4 | avatar: state => state.user.avatar, 5 | visitedViews: state => state.tagsView.visitedViews, 6 | cachedViews: state => state.tagsView.cachedViews, 7 | permission_routes: state => state.permission.routes, 8 | permission_asyncRoutes: state => state.permission.addRoutes, 9 | user_permission: state => state.permission.permission, 10 | } 11 | 12 | export default getters -------------------------------------------------------------------------------- /backend/resources/js/components/Tinymce/toolbar.js: -------------------------------------------------------------------------------- 1 | // Here is a list of the toolbar 2 | // Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols 3 | 4 | const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'] 5 | 6 | export default toolbar 7 | -------------------------------------------------------------------------------- /frontend-api/routes/web.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /frontend-api/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /backend/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 17 | return $request->user(); 18 | }); 19 | -------------------------------------------------------------------------------- /backend/resources/js/components/Tinymce/plugins.js: -------------------------------------------------------------------------------- 1 | // Any plugins you want to use has to be imported 2 | // Detail plugins list see https://www.tinymce.com/docs/plugins/ 3 | // Custom builds see https://www.tinymce.com/download/custom-builds/ 4 | 5 | const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount'] 6 | 7 | export default plugins 8 | -------------------------------------------------------------------------------- /frontend-api/routes/api.php: -------------------------------------------------------------------------------- 1 | get('/user', function (Request $request) { 17 | return $request->user(); 18 | }); 19 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 17 | } 18 | 19 | /** 20 | * Show the application dashboard. 21 | * 22 | * @return \Illuminate\Contracts\Support\Renderable 23 | */ 24 | public function index() 25 | { 26 | return view('home'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/password.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/education.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /backend/resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /backend/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /frontend-api/resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /frontend-api/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /backend/resources/js/directive/permission/permission.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | export default { 4 | inserted(el, binding, vnode) { 5 | const { value } = binding 6 | 7 | if(typeof value == 'string' && value.length > 0){ 8 | if( store.state.user.id == 1 ) return; 9 | 10 | let hasPermission = store.getters.user_permission.includes(value); 11 | 12 | if( !hasPermission ){ 13 | el.parentNode && el.parentNode.removeChild(el) 14 | } 15 | 16 | }else{ 17 | throw new Error(`need roles! Like v-permission="'admin/index'"`) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend/server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/resources/views/index.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Laravel 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /frontend-api/server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/message.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /backend/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /backend/resources/js/api/role.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllRoles() { 4 | return fetch({ 5 | url: 'role', 6 | method: 'get', 7 | }); 8 | } 9 | 10 | export function createRole(data) { 11 | return fetch({ 12 | url: 'role/create', 13 | method: 'post', 14 | data 15 | }); 16 | } 17 | 18 | export function getRole(id) { 19 | return fetch({ 20 | url: 'role/edit', 21 | method: 'get', 22 | params:{id:id} 23 | }); 24 | } 25 | 26 | export function editRole( data ) 27 | { 28 | return fetch({ 29 | url: 'role/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /frontend-api/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Handle Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-web/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /backend/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Echo exposes an expressive API for subscribing to channels and listening 3 | * for events that are broadcast by Laravel. Echo and event broadcasting 4 | * allows your team to easily build robust real-time web applications. 5 | */ 6 | 7 | import Echo from 'laravel-echo' 8 | 9 | window.io = require('socket.io-client') 10 | 11 | // let token = document.head.querySelector('meta[name="csrf-token"]'); 12 | window.Echo = new Echo({ 13 | broadcaster: 'socket.io', 14 | namespace: 'App.Events', 15 | host: window.location.hostname + ':6001', 16 | // auth: { 17 | // headers: { 18 | // 'X-XSRF-TOKEN' : token 19 | // } 20 | // } 21 | }); 22 | -------------------------------------------------------------------------------- /backend/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | // return redirect('/home'); 22 | return $next($request); 23 | } 24 | 25 | return $next($request); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /backend/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | 18 | Broadcast::channel('message.{username}', function ($data, $username) { 19 | return $data['username'] === $username; 20 | }); -------------------------------------------------------------------------------- /frontend-api/resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /common/Models/Users.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 'username' => 'username', 19 | ]; 20 | -------------------------------------------------------------------------------- /frontend-api/app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /backend/routes/web.php: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 37 | -------------------------------------------------------------------------------- /backend/laravel-echo-server.json: -------------------------------------------------------------------------------- 1 | { 2 | "authHost": "http://web.blog.me", 3 | "authEndpoint": "/broadcasting/auth", 4 | "clients": [ 5 | { 6 | "appId": "nick", 7 | "key": "331e6ff29d3aefae6984ae0adf7f57be" 8 | } 9 | ], 10 | "database": "redis", 11 | "databaseConfig": { 12 | "redis": { 13 | "host": "172.17.0.4", 14 | "port": "6379" 15 | } 16 | }, 17 | "devMode": true, 18 | "host": null, 19 | "port": "6001", 20 | "protocol": "http", 21 | "socketio": {}, 22 | "sslCertPath": "", 23 | "sslKeyPath": "", 24 | "sslCertChainPath": "", 25 | "sslPassphrase": "", 26 | "subscribers": { 27 | "http": true, 28 | "redis": true 29 | }, 30 | "apiOriginAllow": { 31 | "allowCors": false, 32 | "allowOrigin": "", 33 | "allowMethods": "", 34 | "allowHeaders": "" 35 | } 36 | } -------------------------------------------------------------------------------- /backend/resources/js/layout/components/Sidebar/FixiOSBug.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | device() { 4 | return this.$store.state.app.device 5 | } 6 | }, 7 | mounted() { 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 10 | this.fixBugIniOS() 11 | }, 12 | methods: { 13 | fixBugIniOS() { 14 | const $subMenu = this.$refs.subMenu 15 | if ($subMenu) { 16 | const handleMouseleave = $subMenu.handleMouseleave 17 | $subMenu.handleMouseleave = (e) => { 18 | if (this.device === 'mobile') { 19 | return 20 | } 21 | handleMouseleave(e) 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /frontend-api/resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have e-mailed your password reset link!', 18 | 'token' => 'This password reset token is invalid.', 19 | 'user' => "We can't find a user with that e-mail address.", 20 | 21 | ]; 22 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/edit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import variables from 'res/sass/element-variables.scss' 2 | import defaultSettings from '@/settings' 3 | 4 | const { showSettings, fixedHeader, sidebarLogo , tagsView} = defaultSettings 5 | 6 | const state = { 7 | theme: variables.theme, 8 | showSettings: showSettings, 9 | fixedHeader: fixedHeader, 10 | sidebarLogo: sidebarLogo, 11 | tagsView: tagsView, 12 | } 13 | 14 | const mutations = { 15 | CHANGE_SETTING: (state, { key, value }) => { 16 | if (state.hasOwnProperty(key)) { 17 | state[key] = value 18 | } 19 | } 20 | } 21 | 22 | const actions = { 23 | changeSetting({ commit }, data) { 24 | commit('CHANGE_SETTING', data) 25 | } 26 | } 27 | 28 | export default { 29 | namespaced: true, 30 | state, 31 | mutations, 32 | actions 33 | } 34 | 35 | -------------------------------------------------------------------------------- /frontend-web/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | 5 | Vue.use(Vuex) 6 | 7 | // https://webpack.js.org/guides/dependency-management/#requirecontext 8 | const modulesFiles = require.context('./modules', true, /\.js$/) 9 | 10 | // you do not need `import app from './modules/app'` 11 | // it will auto require all vuex module from modules file 12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { 13 | // set './app.js' => 'app' 14 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') 15 | const value = modulesFiles(modulePath) 16 | modules[moduleName] = value.default 17 | return modules 18 | }, {}) 19 | 20 | const store = new Vuex.Store({ 21 | modules, 22 | getters 23 | }) 24 | 25 | export default store 26 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/nested.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | 5 | Vue.use(Vuex) 6 | 7 | // https://webpack.js.org/guides/dependency-management/#requirecontext 8 | const modulesFiles = require.context('./modules', true, /\.js$/) 9 | 10 | // you do not need `import app from './modules/app'` 11 | // it will auto require all vuex module from modules file 12 | const modules = modulesFiles.keys().reduce((modules, modulePath) => { 13 | // set './app.js' => 'app' 14 | const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') 15 | const value = modulesFiles(modulePath) 16 | modules[moduleName] = value.default 17 | return modules 18 | }, {}) 19 | 20 | const store = new Vuex.Store({ 21 | modules, 22 | getters 23 | }) 24 | 25 | export default store 26 | -------------------------------------------------------------------------------- /backend/resources/js/api/auth.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function login(data) { 4 | return fetch({ 5 | url: 'login', 6 | method: 'post', 7 | data 8 | }); 9 | } 10 | 11 | export function logout() { 12 | return fetch({ 13 | url: 'logout', 14 | method: 'post', 15 | }); 16 | } 17 | 18 | export function getUserInfo(){ 19 | return fetch({ 20 | url: 'admin/info', 21 | method: 'get', 22 | }); 23 | } 24 | 25 | export function wechat_login( state = '' , mode = 'web') { 26 | return fetch({ 27 | url: 'login/wechat', 28 | method: 'get', 29 | params :{state,mode} 30 | }); 31 | } 32 | 33 | export function unbind_wechat() { 34 | return fetch({ 35 | url: 'admin/unbindWechat', 36 | method: 'put', 37 | }); 38 | } -------------------------------------------------------------------------------- /backend/resources/js/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 32 | 33 | 41 | -------------------------------------------------------------------------------- /frontend-api/database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /frontend-api/app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | parent::boot(); 31 | 32 | // 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /backend/resources/js/api/users.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllUsers( data ) { 4 | return fetch({ 5 | url: 'users', 6 | method: 'post', 7 | params:data 8 | }); 9 | } 10 | 11 | export function addUsers( data ){ 12 | return fetch({ 13 | url: 'users/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getUsers( id ){ 20 | return fetch({ 21 | url: 'users/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function editUsers( data ){ 28 | return fetch({ 29 | url: 'users/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function deleteUsers( id ){ 36 | return fetch({ 37 | url: 'users/delete', 38 | method: 'delete', 39 | params:{id:id}, 40 | }); 41 | } -------------------------------------------------------------------------------- /backend/resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least eight characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /backend/database/migrations/2019_06_07_014457_create_table_admin_user_has_roles.php: -------------------------------------------------------------------------------- 1 | increments('id')->comment('自增 ID'); 18 | $table->smallInteger('user_id'); 19 | $table->smallInteger('role_id'); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('admin_user_has_roles'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /backend/resources/js/api/client.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllClient( data ) { 4 | return fetch({ 5 | url: 'client', 6 | method: 'post', 7 | params:data 8 | }); 9 | } 10 | 11 | export function addClient( data ){ 12 | return fetch({ 13 | url: 'client/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getClient( id ){ 20 | return fetch({ 21 | url: 'client/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function editClient( data ){ 28 | return fetch({ 29 | url: 'client/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function deleteClient( id ){ 36 | return fetch({ 37 | url: 'client/delete', 38 | method: 'delete', 39 | params:{id:id}, 40 | }); 41 | } -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/tree-table.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | json([ 23 | 'code' => $code, 24 | 'msg' => $msg, 25 | 'data' => $data, 26 | ]); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/UserController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 18 | } 19 | 20 | public function getInfo( Request $request ) 21 | { 22 | $user = auth()->user(); 23 | 24 | return [ 25 | 'code' => 1, 26 | 'data' => [ 27 | 'id' => $user->id, 28 | 'username' => $user->username, 29 | 'nickname' => $user->nickname, 30 | 'last_time' => $user->last_time, 31 | 'last_ip' => $user->last_ip, 32 | ] 33 | ]; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | json([ 23 | 'code' => $code, 24 | 'msg' => $msg, 25 | 'data' => $data, 26 | ]); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /backend/database/migrations/2019_06_07_014208_create_table_admin_roles.php: -------------------------------------------------------------------------------- 1 | smallIncrements('id')->comment('角色 ID'); 18 | $table->string('name', 64)->unique()->comment('角色名称'); 19 | $table->string('description')->nullable()->comment('备注'); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('admin_roles'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/Models/AdminRoles.php: -------------------------------------------------------------------------------- 1 | belongsToMany( 17 | AdminRolePermissions::class, 18 | 'admin_role_has_permission', 19 | 'role_id', 20 | 'permission_id' 21 | ); 22 | } 23 | public function users() 24 | { 25 | return $this->belongsToMany( 26 | AdminUser::class, 27 | 'admin_user_has_role', 28 | 'role_id', 29 | 'user_id' 30 | ); 31 | } 32 | 33 | // 给角色添加权限 34 | public function givePermissionTo($permission) 35 | { 36 | return $this->permissions()->save($permission); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /backend/database/migrations/2019_06_07_014412_create_table_admin_role_has_permission.php: -------------------------------------------------------------------------------- 1 | increments('id')->comment('自增 ID'); 18 | $table->smallInteger('role_id'); 19 | $table->smallInteger('permission_id'); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('admin_role_has_permission'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /backend/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(\Common\Models\Users::class, function (Faker $faker) { 20 | return [ 21 | 'user_group_id' => 1, 22 | 'username' => $faker->unique()->userName, 23 | 'nickname' => $faker->name, 24 | 'password' => bcrypt('a123456'), 25 | ]; 26 | }); 27 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/eye.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/sass/variables.scss: -------------------------------------------------------------------------------- 1 | // base color 2 | $blue:#324157; 3 | $light-blue:#3A71A8; 4 | $red:#C03639; 5 | $pink: #E65D6E; 6 | $green: #30B08F; 7 | $tiffany: #4AB7BD; 8 | $yellow:#FEC171; 9 | $panGreen: #30B08F; 10 | 11 | // sidebar 12 | $menuText:#bfcbd9; 13 | $menuActiveText:#409EFF; 14 | $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 15 | 16 | $menuBg:#304156; 17 | $menuHover:#263445; 18 | 19 | $subMenuBg:#1f2d3d; 20 | $subMenuHover:#001528; 21 | 22 | $sideBarWidth: 210px; 23 | 24 | // the :export directive is the magic sauce for webpack 25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 26 | :export { 27 | menuText: $menuText; 28 | menuActiveText: $menuActiveText; 29 | subMenuActiveText: $subMenuActiveText; 30 | menuBg: $menuBg; 31 | menuHover: $menuHover; 32 | subMenuBg: $subMenuBg; 33 | subMenuHover: $subMenuHover; 34 | sideBarWidth: $sideBarWidth; 35 | } 36 | -------------------------------------------------------------------------------- /backend/resources/js/api/permission.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllPermissions(id) { 4 | return fetch({ 5 | url: 'permission', 6 | method: 'get', 7 | params:{id:id} 8 | }); 9 | } 10 | 11 | export function addPermission( data ){ 12 | return fetch({ 13 | url: 'permission/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getPermission( id ){ 20 | return fetch({ 21 | url: 'permission/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function editPermission( data ){ 28 | return fetch({ 29 | url: 'permission/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function deletePermission( id ){ 36 | return fetch({ 37 | url: 'permission/delete', 38 | method: 'delete', 39 | params:{id:id}, 40 | }); 41 | } -------------------------------------------------------------------------------- /backend/resources/sass/element-variables.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * I think element-ui's default theme color is too light for long-term use. 3 | * So I modified the default color and you can modify it to your liking. 4 | **/ 5 | 6 | /* theme color */ 7 | $--color-primary: #1890ff; 8 | $--color-success: #13ce66; 9 | $--color-warning: #FFBA00; 10 | $--color-danger: #ff4949; 11 | // $--color-info: #1E1E1E; 12 | 13 | $--button-font-weight: 400; 14 | 15 | // $--color-text-regular: #1f2d3d; 16 | 17 | $--border-color-light: #dfe4ed; 18 | $--border-color-lighter: #e6ebf5; 19 | 20 | $--table-border:1px solid#dfe6ec; 21 | 22 | /* icon font path, required */ 23 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 24 | 25 | //@import "~element-ui/packages/theme-chalk/src/index"; 26 | 27 | // the :export directive is the magic sauce for webpack 28 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 29 | :export { 30 | theme: $--color-primary; 31 | } 32 | -------------------------------------------------------------------------------- /backend/resources/sass/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /backend/resources/js/api/usergroup.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllUserGroups( data ) { 4 | return fetch({ 5 | url: 'user_group', 6 | method: 'post', 7 | params:data 8 | }); 9 | } 10 | 11 | export function addUserGroup( data ){ 12 | return fetch({ 13 | url: 'user_group/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getUserGroup( id ){ 20 | return fetch({ 21 | url: 'user_group/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function editUserGroup( data ){ 28 | return fetch({ 29 | url: 'user_group/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function deleteUserGroup( id ){ 36 | return fetch({ 37 | url: 'user_group/delete', 38 | method: 'delete', 39 | params:{id:id}, 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /frontend-web/src/api/user.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function userLogin(username, password, captcha, code,real_name) { 4 | const data = { 5 | username, 6 | password, 7 | captcha, 8 | code, 9 | real_name 10 | }; 11 | return fetch({ 12 | url: '/login', 13 | method: 'post', 14 | data 15 | }); 16 | } 17 | 18 | export function logout() { 19 | return fetch({ 20 | url: '/logout', 21 | method: 'post' 22 | }); 23 | } 24 | 25 | export function getUserInfo() { 26 | return fetch({ 27 | url: '/user/info', 28 | method: 'get' 29 | }); 30 | } 31 | 32 | export function modifyPassword(oldpassword, newpassword) { 33 | return fetch({ 34 | url: '/user/Password', 35 | method: 'put', 36 | data: { 37 | oldpassword: oldpassword, 38 | newpassword: newpassword 39 | } 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /backend/resources/js/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'Vue Element Admin', 3 | 4 | /** 5 | * @type {boolean} true | false 6 | * @description Whether show the settings right-panel 7 | */ 8 | showSettings: true, 9 | 10 | /** 11 | * @type {boolean} true | false 12 | * @description Whether need tagsView 13 | */ 14 | tagsView: true, 15 | 16 | /** 17 | * @type {boolean} true | false 18 | * @description Whether fix the header 19 | */ 20 | fixedHeader: false, 21 | 22 | /** 23 | * @type {boolean} true | false 24 | * @description Whether show the logo in sidebar 25 | */ 26 | sidebarLogo: true, 27 | 28 | /** 29 | * @type {string | array} 'production' | ['production', 'development'] 30 | * @description Need show err logs component. 31 | * The default is only used in the production env 32 | * If you want to also use it in dev, you can pass ['production', 'development'] 33 | */ 34 | errorLog: 'production' 35 | } 36 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel后台管理系统 2 | APP_ENV=local 3 | APP_KEY=base64:/fplR5OVRsI0bPmM5wSAIKnOAsljAFYIfR2YR44h+gM= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=pgsql 10 | DB_HOST=localhost 11 | DB_PORT=5432 12 | DB_DATABASE=laravel_admin 13 | DB_USERNAME=postgres 14 | DB_PASSWORD=123456 15 | 16 | BROADCAST_DRIVER=redis 17 | CACHE_DRIVER=redis 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=localhost 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | AWS_ACCESS_KEY_ID= 34 | AWS_SECRET_ACCESS_KEY= 35 | AWS_DEFAULT_REGION=us-east-1 36 | AWS_BUCKET= 37 | 38 | PUSHER_APP_ID= 39 | PUSHER_APP_KEY= 40 | PUSHER_APP_SECRET= 41 | PUSHER_APP_CLUSTER=mt1 42 | 43 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 44 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 45 | -------------------------------------------------------------------------------- /frontend-api/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY=base64:/fplR5OVRsI0bPmM5wSAIKnOAsljAFYIfR2YR44h+gM= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | 9 | DB_CONNECTION=pgsql 10 | DB_HOST=localhost 11 | DB_PORT=5432 12 | DB_DATABASE=laravel_admin 13 | DB_USERNAME=postgres 14 | DB_PASSWORD=123456 15 | 16 | BROADCAST_DRIVER=log 17 | CACHE_DRIVER=file 18 | QUEUE_CONNECTION=sync 19 | SESSION_DRIVER=file 20 | SESSION_LIFETIME=120 21 | 22 | REDIS_HOST=localhost 23 | REDIS_PASSWORD=null 24 | REDIS_PORT=6379 25 | 26 | MAIL_DRIVER=smtp 27 | MAIL_HOST=smtp.mailtrap.io 28 | MAIL_PORT=2525 29 | MAIL_USERNAME=null 30 | MAIL_PASSWORD=null 31 | MAIL_ENCRYPTION=null 32 | 33 | AWS_ACCESS_KEY_ID= 34 | AWS_SECRET_ACCESS_KEY= 35 | AWS_DEFAULT_REGION=us-east-1 36 | AWS_BUCKET= 37 | 38 | PUSHER_APP_ID= 39 | PUSHER_APP_KEY= 40 | PUSHER_APP_SECRET= 41 | PUSHER_APP_CLUSTER=mt1 42 | 43 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 44 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 45 | -------------------------------------------------------------------------------- /backend/app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | 'Illuminate\Auth\Events\Login' => [ 22 | 'App\Listeners\LogSuccessfulLogin', 23 | ], 24 | ]; 25 | 26 | /** 27 | * Register any events for your application. 28 | * 29 | * @return void 30 | */ 31 | public function boot() 32 | { 33 | parent::boot(); 34 | 35 | // 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /frontend-api/database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->text('connection'); 19 | $table->text('queue'); 20 | $table->longText('payload'); 21 | $table->longText('exception'); 22 | $table->timestamp('failed_at')->useCurrent(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('failed_jobs'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | define(User::class, function (Faker $faker) { 20 | return [ 21 | 'name' => $faker->name, 22 | 'email' => $faker->unique()->safeEmail, 23 | 'email_verified_at' => now(), 24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 25 | 'remember_token' => Str::random(10), 26 | ]; 27 | }); 28 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /frontend-api/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | bigIncrements('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->rememberToken(); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('users'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | $this->load(__DIR__.'/Commands'); 39 | 40 | require base_path('routes/console.php'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /backend/resources/views/auth/verify.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
{{ __('Verify Your Email Address') }}
9 | 10 |
11 | @if (session('resent')) 12 | 15 | @endif 16 | 17 | {{ __('Before proceeding, please check your email for a verification link.') }} 18 | {{ __('If you did not receive the email') }}, {{ __('click here to request another') }}. 19 |
20 |
21 |
22 |
23 |
24 | @endsection 25 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/users.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | $this->load(__DIR__.'/Commands'); 39 | 40 | require base_path('routes/console.php'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/permission.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/api/config.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllConfig( data ) { 4 | return fetch({ 5 | url: 'config', 6 | method: 'post', 7 | params:data 8 | }); 9 | } 10 | 11 | export function addConfig( data ){ 12 | return fetch({ 13 | url: 'config/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getConfig( id ){ 20 | return fetch({ 21 | url: 'config/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function settingConfig( data ){ 28 | return fetch({ 29 | url: 'config/setting', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function editConfig( data ){ 36 | return fetch({ 37 | url: 'config/edit', 38 | method: 'put', 39 | data 40 | }); 41 | } 42 | 43 | export function deleteConfig( id ){ 44 | return fetch({ 45 | url: 'config/delete', 46 | method: 'delete', 47 | params:{id:id}, 48 | }); 49 | } -------------------------------------------------------------------------------- /backend/resources/js/store/modules/permission.js: -------------------------------------------------------------------------------- 1 | import { constantRoutes } from '@/router' 2 | import { createRouter } from '@/utils/'; 3 | 4 | 5 | const state = { 6 | routes: [], 7 | addRoutes: [], 8 | permission:[], 9 | } 10 | 11 | const mutations = { 12 | SET_ROUTES: (state, routes) => { 13 | state.addRoutes = routes 14 | state.routes = constantRoutes.concat(routes) 15 | }, 16 | SET_PERMISSION: (state, permission) => { 17 | state.permission = permission; 18 | } 19 | } 20 | 21 | const actions = { 22 | generateRoutes({ commit }, apiRouters) { 23 | return new Promise(resolve => { 24 | let routers = createRouter(apiRouters); 25 | // console.log(routers.asyncRouter,routers.user_permission); 26 | commit('SET_ROUTES', routers.asyncRouter); 27 | commit('SET_PERMISSION', routers.user_permission); 28 | resolve(routers.asyncRouter) 29 | }) 30 | } 31 | } 32 | 33 | export default { 34 | namespaced: true, 35 | state, 36 | mutations, 37 | actions 38 | } 39 | -------------------------------------------------------------------------------- /backend/resources/js/api/admin.js: -------------------------------------------------------------------------------- 1 | import fetch from '@/utils/fetch' 2 | 3 | export function getAllAdmins( data ) { 4 | return fetch({ 5 | url: 'admin', 6 | method: 'get', 7 | params:data 8 | }); 9 | } 10 | 11 | export function addAdmin( data ){ 12 | return fetch({ 13 | url: 'admin/create', 14 | method: 'post', 15 | data 16 | }); 17 | } 18 | 19 | export function getAdminUser( id ){ 20 | return fetch({ 21 | url: 'admin/edit', 22 | method: 'get', 23 | params:{id:id} 24 | }); 25 | } 26 | 27 | export function editAdmin( data ){ 28 | return fetch({ 29 | url: 'admin/edit', 30 | method: 'put', 31 | data 32 | }); 33 | } 34 | 35 | export function deleteAdmin( id ){ 36 | return fetch({ 37 | url: 'admin/delete', 38 | method: 'delete', 39 | params:{id:id}, 40 | }); 41 | } 42 | 43 | export function changePassword( data ){ 44 | return fetch({ 45 | url: 'admin/changePassword', 46 | method: 'put', 47 | data 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /frontend-api/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'postmark' => [ 24 | 'token' => env('POSTMARK_TOKEN'), 25 | ], 26 | 27 | 'ses' => [ 28 | 'key' => env('AWS_ACCESS_KEY_ID'), 29 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 30 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 31 | ], 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/international.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/Http/Requests/CommonIndexRequest.php: -------------------------------------------------------------------------------- 1 | 'required|integer', 29 | 'limit' => 'required|integer', 30 | ]; 31 | } 32 | 33 | /** 34 | * 获取已定义验证规则的错误消息。 35 | * @return array 36 | */ 37 | public function messages() 38 | { 39 | return [ 40 | 'page.required' => '页码不能为空!', 41 | 'page.integer' => '页码必须为数字!', 42 | 'limit.required' => '单页条数不能为空!', 43 | 'limit.integer' => '单页条数必须为数字!', 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /backend/app/Helpers/function.php: -------------------------------------------------------------------------------- 1 | $_value ){ 15 | $_value = (array)$_value; 16 | $_value['extra'] = json_decode($_value['extra'],true); 17 | 18 | if( $_value['parent_id'] == $pid ) { 19 | $_value['child'] = createPermission($data,$_value['id']); 20 | $list[] = $_value; 21 | unset($data[$key]); 22 | } 23 | } 24 | 25 | return $list; 26 | } 27 | 28 | /** 29 | * 获取系统配置,从redis获取缓存2秒 30 | * @param $key 31 | * @param string $default 32 | * @return string 33 | */ 34 | function getSysConfig($key,$default='') 35 | { 36 | $value = Cache::store('apc')->remember( 37 | 'redis:'.$key, 38 | 2, 39 | function() use ($key,$default){ 40 | return Redis::hget('sys_config',$key); 41 | } 42 | ); 43 | 44 | return !empty($value)?$value:$default; 45 | } -------------------------------------------------------------------------------- /backend/app/Http/Requests/ClientCreateRequest.php: -------------------------------------------------------------------------------- 1 | 'required|alpha_num', 29 | 'status' => 'required|boolean', 30 | ]; 31 | } 32 | 33 | /** 34 | * 获取已定义验证规则的错误消息。 35 | * @return array 36 | */ 37 | public function messages() 38 | { 39 | return [ 40 | 'account.required' => '商户名称不能为空!', 41 | 'account.integer' => '商户名称必须为数字!', 42 | 'status.required' => '状态不能为空!', 43 | 'status.boolean' => '状态不正确!', 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/config.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /backend/database/migrations/2019_06_19_004447_create_table_admin_request_log.php: -------------------------------------------------------------------------------- 1 | BigIncrements('id'); 18 | $table->string('username', 20)->comment('用户名'); 19 | $table->string('path', 64)->default('')->comment("访问路径"); 20 | $table->text('request')->default('')->comment("REQUEST"); 21 | $table->timestamp('created_at')->default(DB::raw('LOCALTIMESTAMP'))->comment('访问时间'); 22 | 23 | $table->index(['created_at', 'path', 'username']); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('admin_request_log'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/wechat.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/skill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/views/index.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ env('APP_NAME') }} 7 | 8 | 9 | 10 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | @if (env('APP_ENV') == 'production') 24 | 25 | 26 | @endif 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/people.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend-web/src/views-h5/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 10 | 44 | -------------------------------------------------------------------------------- /backend/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /frontend-api/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/notice.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/views/wechat.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 授权结果 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 | @if( $code == 0 ) 15 | 16 | @else 17 | 18 | @endif 19 |
20 |
21 |

{{ $title }}

22 |

{{$desc}}

23 |
24 |
25 | 28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/OrdersController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 18 | } 19 | 20 | /** 21 | * 22 | */ 23 | public function getIndex(Request $request) 24 | { 25 | $page = (int)$request->get('page', 1); 26 | $limit = (int)$request->get('limit'); 27 | 28 | $start = ($page - 1) * $limit; 29 | 30 | $data = [ 31 | 'total' => 0, 32 | 'orders' => [], 33 | ]; 34 | 35 | $orders = Orders::select([ 36 | '*' 37 | ]) 38 | ->orderBy('id', 'asc') 39 | ->skip($start) 40 | ->take($limit) 41 | ->get(); 42 | 43 | $data['total'] = Orders::count(); 44 | 45 | if (!$orders->isEmpty()) { 46 | $data['orders'] = $orders->toArray(); 47 | } 48 | 49 | return $this->response(1, 'Success!', $data); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/language.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/views/default/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 38 | 39 | -------------------------------------------------------------------------------- /frontend-web/src/assets/css/reset.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 2 | margin: 0; 3 | padding: 0; 4 | border: 0; 5 | font-size: 100%; 6 | font: inherit; 7 | vertical-align: baseline; 8 | } 9 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 10 | display: block; 11 | } 12 | body { 13 | line-height: 1; 14 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing:grayscale; 17 | } 18 | ol, ul { 19 | list-style: none; 20 | } 21 | blockquote, q { 22 | quotes: none; 23 | } 24 | blockquote:before, blockquote:after, q:before, q:after { 25 | content: ''; 26 | content: none; 27 | } 28 | table { 29 | border-spacing: 0; 30 | } -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/eye-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/Http/Controllers/Auth/VerificationController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 38 | $this->middleware('signed')->only('verify'); 39 | $this->middleware('throttle:6,1')->only('verify', 'resend'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /backend/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Unit 14 | 15 | 16 | 17 | ./tests/Feature 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Controllers/Auth/VerificationController.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 38 | $this->middleware('signed')->only('verify'); 39 | $this->middleware('throttle:6,1')->only('verify', 'resend'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /frontend-api/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Unit 14 | 15 | 16 | 17 | ./tests/Feature 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/withdrawal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/Events/NotifyEvent.php: -------------------------------------------------------------------------------- 1 | data = $data; 29 | } 30 | 31 | /** 32 | * Get the channels the event should broadcast on. 33 | * 34 | * @return \Illuminate\Broadcasting\Channel|array 35 | */ 36 | public function broadcastOn() 37 | { 38 | return [new PrivateChannel('message.'.$this->data['username'])]; 39 | } 40 | 41 | // /** 42 | // * 获取广播数据 43 | // * 44 | // * @return array 45 | // */ 46 | // public function broadcastWith(){ 47 | // return $this->user; 48 | // } 49 | } 50 | -------------------------------------------------------------------------------- /backend/app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'App\Policies\ModelPolicy', 18 | ]; 19 | 20 | /** 21 | * Register any authentication / authorization services. 22 | * 23 | * @return void 24 | */ 25 | public function boot() 26 | { 27 | 28 | Gate::before(function ($user, $ability){ 29 | 30 | if ($user->id == 1 ) { 31 | return true; 32 | } 33 | 34 | $permission = AdminRolePermissions::where('rule', '=', $ability)->first(); 35 | 36 | if ($permission && !Gate::has($ability)) { 37 | // 对访问权限定义 Gate 38 | Gate::define($ability, function ($user) use ($permission) { 39 | return $user->hasPermission($permission); 40 | }); 41 | } 42 | }); 43 | 44 | $this->registerPolicies(); 45 | 46 | // 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /backend/resources/js/components/Screenfull/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 50 | 51 | 61 | -------------------------------------------------------------------------------- /backend/resources/js/store/modules/app.js: -------------------------------------------------------------------------------- 1 | 2 | const state = { 3 | sidebar: { 4 | opened: true,//Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, 5 | withoutAnimation: false 6 | }, 7 | device: 'desktop' 8 | } 9 | 10 | const mutations = { 11 | TOGGLE_SIDEBAR: state => { 12 | state.sidebar.opened = !state.sidebar.opened 13 | state.sidebar.withoutAnimation = false 14 | if (state.sidebar.opened) { 15 | // Cookies.set('sidebarStatus', 1) 16 | } else { 17 | // Cookies.set('sidebarStatus', 0) 18 | } 19 | }, 20 | CLOSE_SIDEBAR: (state, withoutAnimation) => { 21 | // Cookies.set('sidebarStatus', 0) 22 | state.sidebar.opened = false 23 | state.sidebar.withoutAnimation = withoutAnimation 24 | }, 25 | TOGGLE_DEVICE: (state, device) => { 26 | state.device = device 27 | } 28 | } 29 | 30 | const actions = { 31 | toggleSideBar({ commit }) { 32 | commit('TOGGLE_SIDEBAR') 33 | }, 34 | closeSideBar({ commit }, { withoutAnimation }) { 35 | commit('CLOSE_SIDEBAR', withoutAnimation) 36 | }, 37 | toggleDevice({ commit }, device) { 38 | commit('TOGGLE_DEVICE', device) 39 | } 40 | } 41 | 42 | export default { 43 | namespaced: true, 44 | state, 45 | mutations, 46 | actions 47 | } 48 | -------------------------------------------------------------------------------- /backend/resources/js/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | 33 | 45 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/wechat_login.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/404.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/zip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const { body } = document 4 | const WIDTH = 992 // refer to Bootstrap's responsive design 5 | 6 | export default { 7 | watch: { 8 | $route(route) { 9 | if (this.device === 'mobile' && this.sidebar.opened) { 10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) 11 | } 12 | } 13 | }, 14 | beforeMount() { 15 | window.addEventListener('resize', this.$_resizeHandler) 16 | }, 17 | beforeDestroy() { 18 | window.removeEventListener('resize', this.$_resizeHandler) 19 | }, 20 | mounted() { 21 | const isMobile = this.$_isMobile() 22 | if (isMobile) { 23 | store.dispatch('app/toggleDevice', 'mobile') 24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 25 | } 26 | }, 27 | methods: { 28 | // use $_ for mixins properties 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential 30 | $_isMobile() { 31 | const rect = body.getBoundingClientRect() 32 | return rect.width - 1 < WIDTH 33 | }, 34 | $_resizeHandler() { 35 | if (!document.hidden) { 36 | const isMobile = this.$_isMobile() 37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') 38 | 39 | if (isMobile) { 40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /backend/resources/sass/element-ui.scss: -------------------------------------------------------------------------------- 1 | // cover some element-ui styles 2 | 3 | .el-breadcrumb__inner, 4 | .el-breadcrumb__inner a { 5 | font-weight: 400 !important; 6 | } 7 | 8 | .el-upload { 9 | input[type="file"] { 10 | display: none !important; 11 | } 12 | } 13 | 14 | .el-upload__input { 15 | display: none; 16 | } 17 | 18 | .cell { 19 | .el-tag { 20 | margin-right: 0px; 21 | } 22 | } 23 | 24 | .small-padding { 25 | .cell { 26 | padding-left: 5px; 27 | padding-right: 5px; 28 | } 29 | } 30 | 31 | .fixed-width { 32 | .el-button--mini { 33 | padding: 7px 10px; 34 | width: 60px; 35 | } 36 | } 37 | 38 | .status-col { 39 | .cell { 40 | padding: 0 10px; 41 | text-align: center; 42 | 43 | .el-tag { 44 | margin-right: 0px; 45 | } 46 | } 47 | } 48 | 49 | // to fixed https://github.com/ElemeFE/element/issues/2461 50 | .el-dialog { 51 | transform: none; 52 | left: 0; 53 | position: relative; 54 | margin: 0 auto; 55 | } 56 | 57 | // refine element ui upload 58 | .upload-container { 59 | .el-upload { 60 | width: 100%; 61 | 62 | .el-upload-dragger { 63 | width: 100%; 64 | height: 200px; 65 | } 66 | } 67 | } 68 | 69 | // dropdown 70 | .el-dropdown-menu { 71 | a { 72 | display: block 73 | } 74 | } 75 | 76 | // fix date-picker ui bug in filter-item 77 | .el-range-editor.el-input__inner { 78 | display: inline-flex !important; 79 | } 80 | 81 | .el-table th { 82 | background-color: #f5f7fa !important; 83 | } 84 | -------------------------------------------------------------------------------- /frontend-api/app/Http/Middleware/EnableCrossRequestMiddleware.php: -------------------------------------------------------------------------------- 1 | isMethod('OPTIONS')){ 20 | $response = response('',200); 21 | }else{ 22 | $response = $next($request); 23 | } 24 | 25 | $origin = $request->server('HTTP_ORIGIN') ? $request->server('HTTP_ORIGIN') : ''; 26 | $allow_origin = [ 27 | 'http://localhost:8080', 28 | 'http://frontend_web.laravel_admin.me', 29 | ]; 30 | if (in_array($origin, $allow_origin)) { 31 | $response->headers->add([ 32 | 'Access-Control-Allow-Origin' => $origin, 33 | 'Access-Control-Allow-Headers' => 'Origin, Content-Type, Access-Token, Cookie, X-CSRF-TOKEN, Accept, Authorization, X-XSRF-TOKEN, x-requested-with', 34 | 'Access-Control-Expose-Headers' => 'Authorization, authenticated', 35 | 'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE', 36 | 'Access-Control-Allow-Credentials' => 'true' 37 | ]); 38 | 39 | } 40 | return $response; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /frontend-web/src/views-web/index/Index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /frontend-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend-web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.19.2", 12 | "babel-plugin-import": "^1.13.0", 13 | "core-js": "^3.6.4", 14 | "element-ui": "^2.13.0", 15 | "node-sass": "^4.13.1", 16 | "normalize.css": "^8.0.1", 17 | "nprogress": "^0.2.0", 18 | "sass-loader": "^8.0.2", 19 | "vant": "^2.6.0", 20 | "vue": "^2.6.11", 21 | "vue-router": "^3.1.5", 22 | "vuex": "^3.1.2", 23 | "webpack-bundle-analyzer-sunburst": "^1.3.0" 24 | }, 25 | "devDependencies": { 26 | "@vue/cli-plugin-babel": "~4.2.0", 27 | "@vue/cli-plugin-eslint": "~4.2.0", 28 | "@vue/cli-plugin-router": "^4.2.2", 29 | "@vue/cli-plugin-vuex": "^4.2.2", 30 | "@vue/cli-service": "~4.2.0", 31 | "babel-eslint": "^10.0.3", 32 | "babel-plugin-component": "^1.1.1", 33 | "eslint": "^6.7.2", 34 | "eslint-plugin-vue": "^6.1.2", 35 | "vue-template-compiler": "^2.6.11" 36 | }, 37 | "eslintConfig": { 38 | "root": true, 39 | "env": { 40 | "node": true 41 | }, 42 | "extends": [ 43 | "plugin:vue/essential", 44 | "eslint:recommended" 45 | ], 46 | "parserOptions": { 47 | "parser": "babel-eslint" 48 | } 49 | }, 50 | "browserslist": [ 51 | "> 1%", 52 | "last 2 versions" 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /backend/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | ], 22 | 23 | 'postmark' => [ 24 | 'token' => env('POSTMARK_TOKEN'), 25 | ], 26 | 27 | 'ses' => [ 28 | 'key' => env('AWS_ACCESS_KEY_ID'), 29 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 30 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 31 | ], 32 | 33 | 'sparkpost' => [ 34 | 'secret' => env('SPARKPOST_SECRET'), 35 | ], 36 | 37 | 'stripe' => [ 38 | 'model' => App\User::class, 39 | 'key' => env('STRIPE_KEY'), 40 | 'secret' => env('STRIPE_SECRET'), 41 | 'webhook' => [ 42 | 'secret' => env('STRIPE_WEBHOOK_SECRET'), 43 | 'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300), 44 | ], 45 | ], 46 | 47 | ]; 48 | -------------------------------------------------------------------------------- /frontend-web/src/views-h5/index/Index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 42 | 43 | 46 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/bug.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/sass/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | 30 | @mixin pct($pct) { 31 | width: #{$pct}; 32 | position: relative; 33 | margin: 0 auto; 34 | } 35 | 36 | @mixin triangle($width, $height, $color, $direction) { 37 | $width: $width/2; 38 | $color-border-style: $height solid $color; 39 | $transparent-border-style: $width solid transparent; 40 | height: 0; 41 | width: 0; 42 | 43 | @if $direction==up { 44 | border-bottom: $color-border-style; 45 | border-left: $transparent-border-style; 46 | border-right: $transparent-border-style; 47 | } 48 | 49 | @else if $direction==right { 50 | border-left: $color-border-style; 51 | border-top: $transparent-border-style; 52 | border-bottom: $transparent-border-style; 53 | } 54 | 55 | @else if $direction==down { 56 | border-top: $color-border-style; 57 | border-left: $transparent-border-style; 58 | border-right: $transparent-border-style; 59 | } 60 | 61 | @else if $direction==left { 62 | border-right: $color-border-style; 63 | border-top: $transparent-border-style; 64 | border-bottom: $transparent-border-style; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /backend/app/Jobs/RefreshConfig.php: -------------------------------------------------------------------------------- 1 | username = $username; 31 | } 32 | 33 | /** 34 | * Execute the job. 35 | * 36 | * @return void 37 | */ 38 | public function handle() 39 | { 40 | // 开始刷新网站配置 41 | Redis::del('sys_config'); 42 | Redis::pipeline(function ($pipe) { 43 | $config_list = Config::select(['key','value'])->where([['parent_id','!=',0],['is_disabled','=',1]])->get(); 44 | foreach($config_list as $config){ 45 | $pipe->hset("sys_config", $config->key,$config->value); 46 | } 47 | }); 48 | 49 | $refresh_data = ['username'=>$this->username,'time'=>date('Y-m-d H:i:s')]; 50 | 51 | event(new NotifyEvent($refresh_data));//['username'=>'admin'] 52 | 53 | // 记录刷新时间 54 | Cache::store('redis')->forever('last_refresh_config', $refresh_data); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /backend/database/migrations/2019_06_04_000000_create_table_admin_users.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('nickname')->comment('用户昵称'); 19 | $table->string('username')->unique()->comment('用户名'); 20 | $table->string('password'); 21 | $table->boolean('is_locked')->default(0)->comment('是否锁定'); 22 | $table->string('unionid')->nullable()->comment('微信登陆唯一ID'); 23 | $table->ipAddress('last_ip')->nullable()->comment('最后一次登录IP'); 24 | $table->timestamp('last_time')->nullable()->comment('最后登录时间'); 25 | $table->string('last_session', 64)->default('')->comment('最近登陆SESSIONID'); 26 | $table->string('google_key', 16)->default('')->comment('谷歌登录器秘钥'); 27 | $table->rememberToken(); 28 | $table->timestamps(); 29 | }); 30 | 31 | DB::table('admin_users')->insert([ 32 | 'nickname' => '超级管理员', 33 | 'username' => 'admin', 34 | 'password' => Hash::make('admin123'), 35 | ]); 36 | } 37 | 38 | /** 39 | * Reverse the migrations. 40 | * 41 | * @return void 42 | */ 43 | public function down() 44 | { 45 | Schema::dropIfExists('admin_users'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/pdf.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/exit-fullscreen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/resources/js/icons/svg/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /frontend-api/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 1024, 48 | 'threads' => 2, 49 | 'time' => 2, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /backend/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /frontend-api/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /backend/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'encrypted' => true, 41 | ], 42 | ], 43 | 44 | 'redis' => [ 45 | 'driver' => 'redis', 46 | 'connection' => 'default', 47 | ], 48 | 49 | 'log' => [ 50 | 'driver' => 'log', 51 | ], 52 | 53 | 'null' => [ 54 | 'driver' => 'null', 55 | ], 56 | 57 | ], 58 | 59 | ]; 60 | -------------------------------------------------------------------------------- /frontend-api/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'useTLS' => true, 41 | ], 42 | ], 43 | 44 | 'redis' => [ 45 | 'driver' => 'redis', 46 | 'connection' => 'default', 47 | ], 48 | 49 | 'log' => [ 50 | 'driver' => 'log', 51 | ], 52 | 53 | 'null' => [ 54 | 'driver' => 'null', 55 | ], 56 | 57 | ], 58 | 59 | ]; 60 | -------------------------------------------------------------------------------- /backend/resources/js/components/Tinymce/dynamicLoadScript.js: -------------------------------------------------------------------------------- 1 | let callbacks = [] 2 | 3 | function loadedTinymce() { 4 | // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144 5 | // check is successfully downloaded script 6 | return window.tinymce 7 | } 8 | 9 | const dynamicLoadScript = (src, callback) => { 10 | const existingScript = document.getElementById(src) 11 | const cb = callback || function() {} 12 | 13 | if (!existingScript) { 14 | const script = document.createElement('script') 15 | script.src = src // src url for the third-party library being loaded. 16 | script.id = src 17 | document.body.appendChild(script) 18 | callbacks.push(cb) 19 | const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd 20 | onEnd(script) 21 | } 22 | 23 | if (existingScript && cb) { 24 | if (loadedTinymce()) { 25 | cb(null, existingScript) 26 | } else { 27 | callbacks.push(cb) 28 | } 29 | } 30 | 31 | function stdOnEnd(script) { 32 | script.onload = function() { 33 | // this.onload = null here is necessary 34 | // because even IE9 works not like others 35 | this.onerror = this.onload = null 36 | for (const cb of callbacks) { 37 | cb(null, script) 38 | } 39 | callbacks = null 40 | } 41 | script.onerror = function() { 42 | this.onerror = this.onload = null 43 | cb(new Error('Failed to load ' + src), script) 44 | } 45 | } 46 | 47 | function ieOnEnd(script) { 48 | script.onreadystatechange = function() { 49 | if (this.readyState !== 'complete' && this.readyState !== 'loaded') return 50 | this.onreadystatechange = null 51 | for (const cb of callbacks) { 52 | cb(null, script) // there is no way to catch loading errors in IE8 53 | } 54 | callbacks = null 55 | } 56 | } 57 | } 58 | 59 | export default dynamicLoadScript 60 | -------------------------------------------------------------------------------- /backend/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | --------------------------------------------------------------------------------