├── console ├── src │ ├── api │ │ ├── backend │ │ │ ├── dictType.ts │ │ │ ├── logLogin.ts │ │ │ ├── logRequest.ts │ │ │ ├── uploadFile.ts │ │ │ ├── gen.ts │ │ │ ├── auth.ts │ │ │ ├── upload.ts │ │ │ ├── uploadGroup.ts │ │ │ ├── menu.ts │ │ │ └── role.ts │ │ └── types │ │ │ ├── log.ts │ │ │ ├── common.ts │ │ │ ├── account.ts │ │ │ ├── role.ts │ │ │ └── file.ts │ ├── assets │ │ ├── 404.gif │ │ ├── images │ │ │ ├── logo.png │ │ │ └── icon_folder.png │ │ └── icons │ │ │ ├── moon.svg │ │ │ └── sun.svg │ ├── components │ │ ├── core │ │ │ ├── basic-arrow │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── iframe-page │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── button │ │ │ │ ├── index.ts │ │ │ │ ├── button.ts │ │ │ │ └── button.vue │ │ │ ├── icon │ │ │ │ ├── index.ts │ │ │ │ ├── src │ │ │ │ │ ├── icons.data.ts │ │ │ │ │ ├── props.ts │ │ │ │ │ ├── SvgIcon.vue │ │ │ │ │ └── icon-font.tsx │ │ │ │ └── Icon.vue │ │ │ ├── pro-config-provider │ │ │ │ └── index.vue │ │ │ └── check-box │ │ │ │ └── index.vue │ │ └── business │ │ │ ├── draggable-modal │ │ │ └── index.ts │ │ │ ├── schema-form │ │ │ ├── src │ │ │ │ ├── components │ │ │ │ │ └── index.ts │ │ │ │ ├── types │ │ │ │ │ ├── index.ts │ │ │ │ │ └── hooks.ts │ │ │ │ ├── hooks │ │ │ │ │ ├── useFormContext.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── useFormEvents.ts │ │ │ │ │ ├── useLabelWidth.ts │ │ │ │ │ └── useForm.tsx │ │ │ │ ├── schema-form-item.ts │ │ │ │ ├── componentMap.ts │ │ │ │ └── helper.ts │ │ │ └── index.ts │ │ │ └── dynamic-table │ │ │ ├── src │ │ │ ├── types │ │ │ │ ├── index.ts │ │ │ │ ├── table.ts │ │ │ │ └── tableAction.ts │ │ │ ├── components │ │ │ │ ├── index.ts │ │ │ │ ├── table-settings │ │ │ │ │ ├── refresh-setting.vue │ │ │ │ │ ├── index.vue │ │ │ │ │ ├── search-setting.vue │ │ │ │ │ ├── fullscreen.vue │ │ │ │ │ └── size-setting.vue │ │ │ │ └── tool-bar │ │ │ │ │ └── index.vue │ │ │ ├── hooks │ │ │ │ ├── index.ts │ │ │ │ ├── useTableContext.ts │ │ │ │ ├── useTableExpand.ts │ │ │ │ ├── useTable.tsx │ │ │ │ └── useScroll.ts │ │ │ └── dynamic-table.config.ts │ │ │ └── index.ts │ ├── layout │ │ ├── tabs │ │ │ └── index.ts │ │ ├── header │ │ │ └── components │ │ │ │ ├── index.ts │ │ │ │ ├── fullscreen │ │ │ │ └── index.vue │ │ │ │ └── setting │ │ │ │ └── constant.ts │ │ ├── footer │ │ │ ├── index.tsx │ │ │ └── index.module.less │ │ ├── menu │ │ │ └── components │ │ │ │ ├── menu-item-content.vue │ │ │ │ ├── menu-item.vue │ │ │ │ └── sub-menu-item.vue │ │ ├── logo │ │ │ └── index.vue │ │ └── index.vue │ ├── styles │ │ ├── reset.css │ │ ├── antdv.override.less │ │ ├── index.less │ │ ├── variables.less │ │ ├── common.less │ │ ├── transition.less │ │ └── theme.less │ ├── enums │ │ ├── fileTypeEnum.ts │ │ ├── cacheEnum.ts │ │ ├── breakpointEnum.ts │ │ └── httpEnum.ts │ ├── router │ │ ├── routes │ │ │ ├── modules │ │ │ │ ├── index.ts │ │ │ │ ├── dashboard.ts │ │ │ │ └── demos.ts │ │ │ ├── outsideLayout.ts │ │ │ ├── index.ts │ │ │ └── basic.ts │ │ ├── constant.ts │ │ ├── asyncModules │ │ │ └── index.ts │ │ └── index.ts │ ├── plugins │ │ ├── assets.ts │ │ ├── antd.ts │ │ ├── editor.ts │ │ ├── index.ts │ │ ├── highlight.ts │ │ └── globalMethods.ts │ ├── views │ │ ├── error │ │ │ ├── comp-not-found.vue │ │ │ └── 404.vue │ │ ├── demos │ │ │ ├── a-map │ │ │ │ └── index.vue │ │ │ └── editor │ │ │ │ └── index.vue │ │ ├── system │ │ │ ├── storage │ │ │ │ └── group │ │ │ │ │ ├── formSchemas.ts │ │ │ │ │ └── columns.tsx │ │ │ ├── monitor │ │ │ │ ├── log │ │ │ │ │ ├── login │ │ │ │ │ │ ├── index.vue │ │ │ │ │ │ └── columns.tsx │ │ │ │ │ └── request │ │ │ │ │ │ └── index.vue │ │ │ │ └── server │ │ │ │ │ └── index.vue │ │ │ └── role │ │ │ │ ├── formSchemas.ts │ │ │ │ └── columns.tsx │ │ ├── dashboard │ │ │ └── index.vue │ │ └── develop │ │ │ ├── dict-type │ │ │ └── columns.tsx │ │ │ └── generate │ │ │ └── components │ │ │ └── table-sheet.vue │ ├── utils │ │ ├── log.ts │ │ ├── dateUtil.ts │ │ ├── awaitTo.ts │ │ ├── helper │ │ │ └── tsxHelper.tsx │ │ ├── urlUtils.ts │ │ ├── propTypes.ts │ │ └── is.ts │ ├── hooks │ │ ├── useModal │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── useFormModal.tsx │ │ ├── useSortable.ts │ │ └── event │ │ │ └── useEventListener.ts │ ├── permission │ │ ├── permCode.ts │ │ └── index.ts │ ├── store │ │ ├── index.ts │ │ └── modules │ │ │ └── keepAlive.ts │ ├── App.vue │ └── main.ts ├── public │ └── favicon.ico ├── tsconfig.node.json ├── index.html ├── .gitignore ├── types │ ├── shims │ │ ├── shims-tsx.d.ts │ │ ├── shims-vue.d.ts │ │ └── shims-app.d.ts │ ├── modules.d.ts │ ├── index.d.ts │ ├── env.d.ts │ └── vue-router.d.ts ├── .eslintrc.cjs ├── .env.production ├── .env ├── unocss.config.ts └── tsconfig.json ├── server ├── config │ ├── dependence.php │ ├── container.php │ ├── exception.php │ ├── view.php │ ├── bootstrap.php │ ├── redis.php │ ├── static.php │ ├── autoload.php │ ├── translation.php │ ├── middleware.php │ ├── cache.php │ ├── app.php │ ├── server.php │ ├── log.php │ ├── database.php │ ├── session.php │ ├── process.php │ └── env.php ├── app │ ├── generate │ │ ├── service │ │ │ ├── stub │ │ │ │ ├── vue │ │ │ │ │ ├── api │ │ │ │ │ │ ├── request │ │ │ │ │ │ │ └── post.stub │ │ │ │ │ │ ├── request.stub │ │ │ │ │ │ └── types.stub │ │ │ │ │ └── DynamicTable │ │ │ │ │ │ ├── formSchemas.stub │ │ │ │ │ │ ├── columns.stub │ │ │ │ │ │ ├── function.stub │ │ │ │ │ │ └── index.stub │ │ │ │ └── php │ │ │ │ │ ├── route.stub │ │ │ │ │ ├── logic.stub │ │ │ │ │ ├── controller.stub │ │ │ │ │ ├── controller │ │ │ │ │ ├── detailController.stub │ │ │ │ │ ├── listsController.stub │ │ │ │ │ ├── deleteController.stub │ │ │ │ │ ├── createController.stub │ │ │ │ │ └── updateController.stub │ │ │ │ │ ├── validate.stub │ │ │ │ │ ├── validate │ │ │ │ │ ├── createValidate.stub │ │ │ │ │ └── updateValidate.stub │ │ │ │ │ ├── logic │ │ │ │ │ ├── createLogic.stub │ │ │ │ │ ├── deleteLogic.stub │ │ │ │ │ ├── listsLogic.stub │ │ │ │ │ ├── updateLogic.stub │ │ │ │ │ └── detailLogic.stub │ │ │ │ │ └── model.stub │ │ │ └── backend │ │ │ │ └── ModelService.php │ │ └── controller │ │ │ ├── TestController.php │ │ │ └── GenerateController.php │ ├── common │ │ ├── model │ │ │ ├── system │ │ │ │ ├── LogLoginModel.php │ │ │ │ ├── LogMySQLModel.php │ │ │ │ ├── RoleMenuModel.php │ │ │ │ ├── AdminRoleModel.php │ │ │ │ ├── MenuModel.php │ │ │ │ ├── RoleModel.php │ │ │ │ ├── AdminModel.php │ │ │ │ └── LogRequestModel.php │ │ │ ├── upload │ │ │ │ ├── FileModel.php │ │ │ │ └── GroupModel.php │ │ │ └── BaseModel.php │ │ └── enum │ │ │ └── RedisKeyEnum.php │ ├── admin │ │ ├── logic │ │ │ └── system │ │ │ │ ├── AdminLogic.php │ │ │ │ └── LogLoginLogic.php │ │ ├── controller │ │ │ ├── system │ │ │ │ ├── MonitorController.php │ │ │ │ ├── LogLoginController.php │ │ │ │ ├── LogRequestController.php │ │ │ │ └── RoleController.php │ │ │ ├── TestController.php │ │ │ ├── upload │ │ │ │ └── FileController.php │ │ │ ├── AccountController.php │ │ │ └── common │ │ │ │ └── UploadController.php │ │ ├── validate │ │ │ └── upload │ │ │ │ └── GroupValidate.php │ │ └── service │ │ │ └── system │ │ │ └── PermissionsService.php │ └── middleware │ │ ├── ActionMiddleware.php │ │ └── CrossMiddleware.php ├── windows.bat ├── public │ ├── favicon.ico │ ├── file_icons │ │ ├── file │ │ │ ├── 7z.png │ │ │ ├── doc.png │ │ │ ├── docx.png │ │ │ ├── pdf.png │ │ │ ├── ppt.png │ │ │ ├── pptx.png │ │ │ ├── rar.png │ │ │ ├── txt.png │ │ │ ├── xls.png │ │ │ ├── xlsx.png │ │ │ └── zip.png │ │ └── video │ │ │ ├── avi.png │ │ │ ├── flv.png │ │ │ ├── mkv.png │ │ │ ├── mp4.png │ │ │ ├── wmv.png │ │ │ └── cover.png │ └── 404.html ├── start.php ├── .gitignore ├── support │ ├── exception │ │ ├── CodeMessageException.php │ │ └── RespBusinessException.php │ ├── Request.php │ └── Response.php ├── LICENSE └── composer.json └── .gitignore /console/src/api/backend/dictType.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/config/dependence.php: -------------------------------------------------------------------------------- 1 | support\exception\Handler::class, 5 | ]; -------------------------------------------------------------------------------- /server/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fluox-Etine/EvoAdmin/HEAD/server/public/favicon.ico -------------------------------------------------------------------------------- /console/src/components/business/draggable-modal/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DraggableModal } from './index.vue'; 2 | -------------------------------------------------------------------------------- /console/src/styles/reset.css: -------------------------------------------------------------------------------- 1 | a:focus, 2 | a:active, 3 | button, 4 | div, 5 | svg, 6 | span { 7 | outline: none; 8 | } 9 | -------------------------------------------------------------------------------- /server/config/view.php: -------------------------------------------------------------------------------- 1 | Raw::class 7 | ]; 8 | -------------------------------------------------------------------------------- /console/src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fluox-Etine/EvoAdmin/HEAD/console/src/assets/images/logo.png -------------------------------------------------------------------------------- /console/src/components/business/schema-form/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ApiSelect } from './ApiSelect.vue'; 2 | -------------------------------------------------------------------------------- /console/src/components/core/iframe-page/index.ts: -------------------------------------------------------------------------------- 1 | import IFramePage from './index.vue'; 2 | 3 | export default IFramePage; 4 | -------------------------------------------------------------------------------- /server/public/file_icons/file/7z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Fluox-Etine/EvoAdmin/HEAD/server/public/file_icons/file/7z.png -------------------------------------------------------------------------------- /server/start.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | ({}); 7 | -------------------------------------------------------------------------------- /console/src/components/business/schema-form/src/types/hooks.ts: -------------------------------------------------------------------------------- 1 | export interface AdvanceState { 2 | isAdvanced: boolean; 3 | hideAdvanceBtn: boolean; 4 | isLoad: boolean; 5 | actionSpan: number; 6 | } 7 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | /runtime 2 | /.idea 3 | /.vscode 4 | /vendor 5 | *.log 6 | .env 7 | /tests/tmp 8 | /tests/.phpunit.result.cache 9 | /config/database.php 10 | /config/redis.php 11 | /public/uploads 12 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/vue/DynamicTable/formSchemas.stub: -------------------------------------------------------------------------------- 1 | import type { FormSchema } from '@/components/business/schema-form/'; 2 | 3 | export const formSchemas: FormSchema[] = [ 4 | {COLUMNS} 5 | ]; -------------------------------------------------------------------------------- /console/src/components/core/button/index.ts: -------------------------------------------------------------------------------- 1 | import AButton from './button.vue'; 2 | 3 | export default AButton; 4 | 5 | export const Button = AButton; 6 | 7 | export * from './button'; 8 | 9 | export { AButton }; 10 | -------------------------------------------------------------------------------- /server/config/redis.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'host' => '127.0.0.1', 6 | 'password' => '123456', 7 | 'port' => 6379, 8 | 'database' => 1, 9 | ], 10 | ]; 11 | -------------------------------------------------------------------------------- /console/src/styles/antdv.override.less: -------------------------------------------------------------------------------- 1 | .ant-col { 2 | width: 100%; 3 | } 4 | 5 | body { 6 | .ant-message { 7 | z-index: 999999; 8 | } 9 | } 10 | 11 | .ant-image-preview-root img { 12 | display: unset; 13 | } 14 | -------------------------------------------------------------------------------- /console/src/components/business/dynamic-table/index.ts: -------------------------------------------------------------------------------- 1 | export { default as DynamicTable } from './src/dynamic-table.vue'; 2 | 3 | export * from './src/types/'; 4 | export * from './src/hooks/'; 5 | export * from './src/dynamic-table'; 6 | -------------------------------------------------------------------------------- /console/src/styles/index.less: -------------------------------------------------------------------------------- 1 | @root-entry-name: variable; 2 | 3 | @import './reset.css'; 4 | @import './theme.less'; 5 | @import './transition.less'; 6 | @import './common.less'; 7 | @import './variables.less'; 8 | @import './antdv.override.less'; 9 | -------------------------------------------------------------------------------- /server/config/static.php: -------------------------------------------------------------------------------- 1 | true, 8 | 'middleware' => [ // Static file Middleware 9 | //app\middleware\StaticFile::class, 10 | ], 11 | ]; -------------------------------------------------------------------------------- /server/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 404 Not Found - EvoAdmin 4 | 5 | 6 |
7 |

404 Not Found

8 |
9 |
10 |
EvoAdmin
11 | 12 | 13 | -------------------------------------------------------------------------------- /console/src/layout/header/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FullScreen } from './fullscreen/index.vue'; 2 | export { default as ProjectSetting } from './setting/index.vue'; 3 | export { default as LayoutBreadcrumb } from './breadcrumb/index.vue'; 4 | -------------------------------------------------------------------------------- /console/src/plugins/antd.ts: -------------------------------------------------------------------------------- 1 | import type {App} from 'vue'; 2 | import 'ant-design-vue/dist/reset.css'; 3 | import {AButton} from '@/components/core/button/'; 4 | 5 | export function setupAntd(app: App) { 6 | app.component('AButton', AButton); 7 | } 8 | -------------------------------------------------------------------------------- /server/app/common/model/system/LogLoginModel.php: -------------------------------------------------------------------------------- 1 | ({}); 8 | -------------------------------------------------------------------------------- /server/app/common/model/system/AdminRoleModel.php: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /console/src/enums/cacheEnum.ts: -------------------------------------------------------------------------------- 1 | /** 用户token */ 2 | export const ACCESS_TOKEN_KEY = 'ACCESS_TOKEN'; 3 | 4 | /** 国际化 */ 5 | export const LOCALE_KEY = 'LOCALE__'; 6 | 7 | /** 主题色 */ 8 | export const THEME_KEY = 'THEME__'; 9 | 10 | /** 用户信息 */ 11 | export const USER_INFO_KEY = 'USER__INFO__'; 12 | -------------------------------------------------------------------------------- /console/src/utils/log.ts: -------------------------------------------------------------------------------- 1 | const projectName = import.meta.env.VITE_APP_TITLE; 2 | 3 | export function warn(message: string) { 4 | console.warn(`[${projectName} warn]:${message}`); 5 | } 6 | 7 | export function error(message: string) { 8 | throw new Error(`[${projectName} error]:${message}`); 9 | } 10 | -------------------------------------------------------------------------------- /console/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true, 8 | "strict": true 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /server/app/common/model/system/MenuModel.php: -------------------------------------------------------------------------------- 1 | ; 5 | export const baseColumns: TableColumnItem[] = [ 6 | {COLUMNS} 7 | ]; -------------------------------------------------------------------------------- /console/src/styles/variables.less: -------------------------------------------------------------------------------- 1 | // @import 'ant-design-vue/lib/style/themes/default.less'; 2 | 3 | // @header-height: 64px; 4 | // @footer-height: 70px; 5 | // @primary-color: #00b96b; 6 | 7 | :root { 8 | --app-header-height: 64px; 9 | --app-footer-height: 0px; 10 | --app-primary-color: #00b96b; 11 | } 12 | -------------------------------------------------------------------------------- /server/config/autoload.php: -------------------------------------------------------------------------------- 1 | [ 5 | base_path() . '/app/functions.php', 6 | base_path() . '/support/Request.php', 7 | base_path() . '/support/Response.php', 8 | // 加载自己的工具函数 9 | base_path() . '/support/utils.php', 10 | ] 11 | ]; 12 | -------------------------------------------------------------------------------- /console/src/views/demos/a-map/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.dll 3 | *.so 4 | *.dylib 5 | 6 | # Test binary, built with `go test -c` 7 | *.test 8 | 9 | # Output of the go coverage tool, specifically when used with LiteIDE 10 | *.out 11 | 12 | # Dependency directories (remove the comment below to include it) 13 | # vendor/ 14 | /.idea 15 | -------------------------------------------------------------------------------- /console/src/components/business/dynamic-table/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useTable'; 2 | export * from './useTableContext'; 3 | export * from './useTableForm'; 4 | export * from './useTableState'; 5 | export * from './useTableMethods'; 6 | export * from './useColumns'; 7 | export * from './useEditable'; 8 | export * from './useScroll'; 9 | -------------------------------------------------------------------------------- /console/src/hooks/useModal/index.ts: -------------------------------------------------------------------------------- 1 | import { installUseModal, useModal } from './useModal'; 2 | import { useFormModal } from './useFormModal'; 3 | import type { App } from 'vue'; 4 | 5 | const install = (app: App) => { 6 | installUseModal(app); 7 | }; 8 | 9 | export { useModal, useFormModal, install }; 10 | 11 | export default install; 12 | -------------------------------------------------------------------------------- /server/config/translation.php: -------------------------------------------------------------------------------- 1 | 'zh_CN', 9 | // Fallback language 10 | 'fallback_locale' => ['zh_CN', 'en'], 11 | // Folder where language files are stored 12 | 'path' => base_path() . '/resource/translations', 13 | ]; -------------------------------------------------------------------------------- /console/src/components/core/icon/index.ts: -------------------------------------------------------------------------------- 1 | export { default as IconPicker } from './src/IconPicker.vue'; 2 | export { default as SvgIcon } from './src/SvgIcon.vue'; 3 | export { default as Icon } from './Icon.vue'; 4 | export { default as IconFont } from './src/icon-font'; 5 | 6 | export * from './src/props'; 7 | 8 | export { setupIcons } from './src/icons.data'; 9 | -------------------------------------------------------------------------------- /console/src/permission/permCode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 从后端接口获取:/api/system/menus/permissions 3 | * @description 权限列表, 仅供开发时提供 ts 类型提示,无实际作用 4 | */ 5 | import * as Api from '@/api/backend/menu'; 6 | 7 | const permissions = Api.menuGetPermissions() 8 | export type PermissionType = (typeof permissions)[string]; 9 | 10 | console.log('permissionsCode', permissions); 11 | -------------------------------------------------------------------------------- /console/src/components/business/schema-form/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SchemaFormItem } from './src/schema-form-item.vue'; 2 | export { default as SchemaForm } from './src/schema-form.vue'; 3 | 4 | export * from './src/types/'; 5 | export * from './src/schema-form'; 6 | export * from './src/schema-form-item'; 7 | export * from './src/hooks/'; 8 | export * from './src/components/'; 9 | -------------------------------------------------------------------------------- /console/src/assets/icons/moon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/logic.stub: -------------------------------------------------------------------------------- 1 | $this->getCode(), 'message' => $this->getMessage()]); 13 | } 14 | } -------------------------------------------------------------------------------- /console/src/plugins/highlight.ts: -------------------------------------------------------------------------------- 1 | import hljsVuePlugin from '@highlightjs/vue-plugin'; 2 | import hljs from 'highlight.js/lib/core'; 3 | import php from 'highlight.js/lib/languages/php'; 4 | import 'highlight.js/styles/a11y-dark.css' 5 | import type {App} from "vue"; 6 | 7 | hljs.registerLanguage('php', php) 8 | 9 | export function setupHighlight(app: App) { 10 | app.use(hljsVuePlugin); 11 | } -------------------------------------------------------------------------------- /server/app/common/model/system/AdminModel.php: -------------------------------------------------------------------------------- 1 | config('env.http.error_code'), 'message' => $this->getMessage()]); 13 | } 14 | } -------------------------------------------------------------------------------- /console/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Evo Admin 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /server/config/middleware.php: -------------------------------------------------------------------------------- 1 | [ 6 | // 跨域中间件 7 | app\middleware\CrossMiddleware::class, 8 | ], 9 | // admin 中间件 10 | 'admin' => [ 11 | // 日志中间件 12 | app\middleware\LogMiddleware::class, 13 | ], 14 | // 代码生成器中间件 15 | 'generate' => [ 16 | // 日志中间件 17 | app\middleware\LogMiddleware::class, 18 | ] 19 | ]; -------------------------------------------------------------------------------- /console/src/router/routes/outsideLayout.ts: -------------------------------------------------------------------------------- 1 | import type { RouteRecordRaw } from 'vue-router'; 2 | import { LOGIN_NAME } from '@/router/constant'; 3 | 4 | /** 5 | * layout布局之外的路由 6 | */ 7 | export const LoginRoute: RouteRecordRaw = { 8 | path: '/login', 9 | name: LOGIN_NAME, 10 | component: () => import('@/views/login/index.vue'), 11 | meta: { 12 | title: '登录', 13 | }, 14 | }; 15 | 16 | export default [LoginRoute]; 17 | -------------------------------------------------------------------------------- /server/app/generate/controller/TestController.php: -------------------------------------------------------------------------------- 1 | where('adcode', $randId)->first(); 14 | return renderSuccess(compact('detail')); 15 | } 16 | } -------------------------------------------------------------------------------- /server/config/cache.php: -------------------------------------------------------------------------------- 1 | 'file', 5 | 'stores' => [ 6 | 'file' => [ 7 | 'driver' => 'file', 8 | 'path' => runtime_path('cache') 9 | ], 10 | 'redis' => [ 11 | 'driver' => 'redis', 12 | 'connection' => 'default' 13 | ], 14 | 'array' => [ 15 | 'driver' => 'array' 16 | ] 17 | ] 18 | ]; 19 | -------------------------------------------------------------------------------- /console/src/components/business/dynamic-table/src/hooks/useTableContext.ts: -------------------------------------------------------------------------------- 1 | import { injectLocal, provideLocal } from '@vueuse/core'; 2 | import type { DynamicTableType } from '../types'; 3 | 4 | const key = Symbol('dynamic-table'); 5 | 6 | export function createTableContext(instance: DynamicTableType) { 7 | provideLocal(key, instance); 8 | } 9 | 10 | export function useTableContext() { 11 | return injectLocal(key) as DynamicTableType; 12 | } 13 | -------------------------------------------------------------------------------- /console/src/components/business/schema-form/src/hooks/useFormContext.ts: -------------------------------------------------------------------------------- 1 | import { injectLocal, provideLocal } from '@vueuse/core'; 2 | import type { SchemaFormType } from './'; 3 | 4 | const key = Symbol('schema-form'); 5 | 6 | export async function createFormContext(instance: SchemaFormType) { 7 | provideLocal(key, instance); 8 | } 9 | 10 | export function useFormContext(formProps = {}) { 11 | return injectLocal(key, formProps) as SchemaFormType; 12 | } 13 | -------------------------------------------------------------------------------- /server/app/admin/controller/system/MonitorController.php: -------------------------------------------------------------------------------- 1 | php_uname('s'), 14 | 'cpu' => cpu_count(), 15 | 'cpu_usage' => sys_getloadavg(), 16 | 'load_average' => sys_getloadavg(), 17 | ]; 18 | 19 | } 20 | } -------------------------------------------------------------------------------- /server/config/app.php: -------------------------------------------------------------------------------- 1 | true, 7 | 'error_reporting' => E_ALL, 8 | 'default_timezone' => 'Asia/Shanghai', 9 | 'request_class' => Request::class, 10 | 'public_path' => base_path() . DIRECTORY_SEPARATOR . 'public', 11 | 'runtime_path' => base_path(false) . DIRECTORY_SEPARATOR . 'runtime', 12 | 'controller_suffix' => 'Controller', 13 | 'controller_reuse' => false, 14 | ]; 15 | -------------------------------------------------------------------------------- /console/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | *.tsbuildinfo 31 | -------------------------------------------------------------------------------- /console/src/api/backend/logLogin.ts: -------------------------------------------------------------------------------- 1 | import {request, type RequestOptions} from '@/utils/request'; 2 | 3 | /** 登录日志 列表方法 POST /system/login/log/list */ 4 | export async function list(body: any, options?: RequestOptions) { 5 | return request('/system/log/login/list', { 6 | method: 'POST', 7 | headers: { 8 | 'Content-Type': 'application/json', 9 | }, 10 | data: body, 11 | ...(options || {}), 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/controller.stub: -------------------------------------------------------------------------------- 1 | `__persisted__${id}`, 10 | auto: false, 11 | }), 12 | ); 13 | 14 | export function setupStore(app: App) { 15 | app.use(store); 16 | } 17 | 18 | export { store }; 19 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/controller/detailController.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 获取{NOTES}详情 4 | * @param Request $request 5 | * @return Response 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public function detail(Request $request): Response 10 | { 11 | $params = $request->post(); 12 | $result = {UPPER_CAMEL_NAME}Logic::handleDetail($params); 13 | return renderSuccess($result); 14 | } -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/controller/listsController.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 获取{NOTES}列表 4 | * @param Request $request 5 | * @return Response 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public function list(Request $request): Response 10 | { 11 | $params = $request->post(); 12 | $list = {UPPER_CAMEL_NAME}Logic::handleLists($params); 13 | return renderSuccess($list,'列表获取成功'); 14 | } -------------------------------------------------------------------------------- /console/src/api/types/log.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 2 | declare namespace API { 3 | 4 | /** 列表参数 */ 5 | type SystemLoginLogListDto = { 6 | /** 页码 */ 7 | page?: number; 8 | /** 每页条数 */ 9 | pageSize?: number; 10 | }; 11 | 12 | /** 列表参数 */ 13 | type SystemLogRequestListDto = { 14 | /** 页码 */ 15 | page?: number; 16 | /** 每页条数 */ 17 | pageSize?: number; 18 | }; 19 | } -------------------------------------------------------------------------------- /console/src/router/constant.ts: -------------------------------------------------------------------------------- 1 | export const LOGIN_NAME = 'Login'; 2 | 3 | export const REDIRECT_NAME = 'Redirect'; 4 | 5 | export const PARENT_LAYOUT_NAME = 'ParentLayout'; 6 | 7 | export const PAGE_NOT_FOUND_NAME = 'PageNotFound'; 8 | 9 | // 路由白名单 10 | export const whiteNameList = [LOGIN_NAME, 'icons', 'error', 'error-404'] as const; // no redirect whitelist 11 | 12 | export type WhiteNameList = typeof whiteNameList; 13 | 14 | export type WhiteName = (typeof whiteNameList)[number]; 15 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/validate.stub: -------------------------------------------------------------------------------- 1 | post(); 12 | $result = {UPPER_CAMEL_NAME}Logic::handleDelete($params); 13 | return $result ? renderSuccess('删除成功') : renderError('删除失败'); 14 | } -------------------------------------------------------------------------------- /console/src/layout/footer/index.tsx: -------------------------------------------------------------------------------- 1 | import { defineComponent } from 'vue'; 2 | import { Layout } from 'ant-design-vue'; 3 | import styles from './index.module.less'; 4 | 5 | const { Footer: ALayoutFooter } = Layout; 6 | 7 | export default defineComponent({ 8 | name: 'PageFooter', 9 | components: { ALayoutFooter }, 10 | setup() { 11 | return () => ( 12 | <> 13 | 14 | 15 | 16 | ); 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /console/src/plugins/globalMethods.ts: -------------------------------------------------------------------------------- 1 | import type { App } from 'vue'; 2 | 3 | // import useFormModal from '@/hooks/useFormModal' 4 | // import useModal from '@/hooks/useModal/index'; 5 | import permission from '@/permission'; 6 | /** 7 | * 注册全局方法 8 | * @param app 9 | */ 10 | export function setupGlobalMethods(app: App) { 11 | app.use(permission); 12 | // app.use(useFormModal) 13 | // app.use(useModal); 14 | // 全局挂载Reflect反射对象,以便在vue模板中使用 15 | app.config.globalProperties.Reflect = Reflect; 16 | } 17 | -------------------------------------------------------------------------------- /console/types/shims/shims-tsx.d.ts: -------------------------------------------------------------------------------- 1 | import type { VNode } from 'vue'; 2 | import type Vue from 'vue'; 3 | 4 | declare module '*.tsx' { 5 | import Vue from 'compatible-vue'; 6 | export default Vue; 7 | } 8 | 9 | declare global { 10 | namespace JSX { 11 | // tslint:disable no-empty-interface 12 | type Element = VNode; 13 | // tslint:disable no-empty-interface 14 | type ElementClass = Vue; 15 | interface IntrinsicElements { 16 | [elem: string]: any; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/controller/createController.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 添加{NOTES} 4 | * @param Request $request 5 | * @return Response 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public function create(Request $request): Response 10 | { 11 | $params = $request->post();{VALIDATE} 12 | $result = {UPPER_CAMEL_NAME}Logic::handleCreate($params); 13 | return $result ? renderSuccess('添加成功') : renderError('添加失败'); 14 | } -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/controller/updateController.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 编辑{NOTES} 4 | * @param Request $request 5 | * @return Response 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public function update(Request $request): Response 10 | { 11 | $params = $request->post();{VALIDATE} 12 | $result = {UPPER_CAMEL_NAME}Logic::handleUpdate($params); 13 | return $result ? renderSuccess('修改成功') : renderError('修改失败'); 14 | } -------------------------------------------------------------------------------- /server/app/admin/controller/TestController.php: -------------------------------------------------------------------------------- 1 | file('iFile'); 14 | // $result = UploadService::handleUpload($file); 15 | // return renderSuccess($result); 16 | // } catch (\Exception $e) { 17 | // return renderError($e->getMessage()); 18 | // } 19 | } 20 | } -------------------------------------------------------------------------------- /console/types/modules.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue'; 3 | const Component: DefineComponent<{}, {}, any>; 4 | export default Component; 5 | } 6 | 7 | declare module 'ant-design-vue/es/locale/*' { 8 | import type { Locale } from 'ant-design-vue/types/locale-provider'; 9 | const locale: Locale & ReadonlyRecordable; 10 | export default locale as Locale & ReadonlyRecordable; 11 | } 12 | 13 | declare module 'virtual:*' { 14 | const result: any; 15 | export default result; 16 | } 17 | -------------------------------------------------------------------------------- /server/app/common/model/system/LogRequestModel.php: -------------------------------------------------------------------------------- 1 | getMessage()); 17 | } 18 | } -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/validate/updateValidate.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 编辑数据验证 4 | * @param array $params 5 | * @return void 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public static function updateValidate(array $params): void 10 | { 11 | try { 12 | v::input($params, [ 13 | {UPDATE_VALIDATE} 14 | ]); 15 | } catch (ValidationException $e) { 16 | throw new RespBusinessException($e->getMessage()); 17 | } 18 | } -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/logic/createLogic.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 添加{NOTES} 4 | * @param array $params 5 | * @return bool 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public static function handleCreate(array $params): bool 10 | { 11 | try { 12 | return {UPPER_CAMEL_NAME}Model::insert([ 13 | {CREATE_DATA} 14 | ]) != false; 15 | } catch (\Exception $e) { 16 | throw new RespBusinessException('创建数据异常'); 17 | } 18 | } -------------------------------------------------------------------------------- /console/src/components/core/icon/src/icons.data.ts: -------------------------------------------------------------------------------- 1 | import { addCollection } from '@iconify/vue'; 2 | 3 | import ep from '@iconify-json/ep/icons.json'; 4 | import antDesign from '@iconify-json/ant-design/icons.json'; 5 | 6 | export const icons = { 'Ant Design': antDesign, 'Element Plus': ep } as const; 7 | 8 | export type DefaultIconsType = 9 | | `ep:${keyof typeof ep.icons}` 10 | | `ant-design:${keyof typeof antDesign.icons}`; 11 | 12 | export const setupIcons = () => { 13 | Object.values(icons).forEach((item) => addCollection(item)); 14 | }; 15 | -------------------------------------------------------------------------------- /server/app/common/enum/RedisKeyEnum.php: -------------------------------------------------------------------------------- 1 | where('{PK}', $params['{WHERE_PK}'])->delete() != false; 13 | } catch (\Exception $e) { 14 | throw new RespBusinessException('删除数据异常'); 15 | } 16 | } -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/logic/listsLogic.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 获取{NOTES}列表 4 | * @param array $params 5 | * @return array 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public static function handleLists(array $params): array 10 | { 11 | try {{FILTER_DATA} 12 | $list = {UPPER_CAMEL_NAME}Model::query(){SQL_CHAIN} 13 | {FORMAT_DATA} 14 | } catch (\Exception $e) { 15 | throw new RespBusinessException('查询数据异常'); 16 | } 17 | } -------------------------------------------------------------------------------- /console/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution') 3 | 4 | module.exports = { 5 | root: true, 6 | 'extends': [ 7 | 'plugin:vue/vue3-essential', 8 | 'eslint:recommended', 9 | '@vue/eslint-config-typescript', 10 | ], 11 | rules: { 12 | // ...其他规则 13 | "vue/multi-word-component-names": ["error", { 14 | "ignores": ["index"] // 忽略名为 'index' 的组件 15 | }] 16 | }, 17 | parserOptions: { 18 | ecmaVersion: 'latest' 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/model.stub: -------------------------------------------------------------------------------- 1 | 2 | 5 | {{ item?.meta?.title }} 6 | 7 | 8 | 23 | -------------------------------------------------------------------------------- /console/src/router/routes/index.ts: -------------------------------------------------------------------------------- 1 | import outsideLayout from './outsideLayout'; 2 | import basic from './basic'; 3 | import type { RouteRecordRaw } from 'vue-router'; 4 | 5 | export const rootRoute: RouteRecordRaw = { 6 | path: '/', 7 | name: 'Layout', 8 | redirect: '/dashboard', 9 | component: () => import('@/layout/index.vue'), 10 | meta: { 11 | title: '根路由', 12 | }, 13 | children: [], 14 | }; 15 | 16 | export const basicRoutes: Array = [ 17 | rootRoute, 18 | // Layout之外的路由 19 | ...outsideLayout, 20 | // 基础路由 21 | ...basic, 22 | ]; 23 | -------------------------------------------------------------------------------- /console/src/assets/icons/sun.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/logic/updateLogic.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 更新{NOTES} 4 | * @param array $params 5 | * @return bool 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public static function handleUpdate(array $params): bool 10 | { 11 | try { 12 | return {UPPER_CAMEL_NAME}Model::query()->where('{PK}', $params['{WHERE_PK}'])->update([ 13 | UPDATE_DATA 14 | ]) != false; 15 | } catch (\Exception $e) { 16 | throw new RespBusinessException('编辑数据异常'); 17 | } 18 | } -------------------------------------------------------------------------------- /console/src/utils/dateUtil.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Independent time operation tool to facilitate subsequent switch to dayjs 3 | */ 4 | import dayjs from 'dayjs'; 5 | 6 | const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'; 7 | const DATE_FORMAT = 'YYYY-MM-DD'; 8 | 9 | export function formatToDateTime(date?: dayjs.ConfigType, format = DATE_TIME_FORMAT): string { 10 | return dayjs(date * 1000).format(format); 11 | } 12 | 13 | export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): string { 14 | return dayjs(date).format(format); 15 | } 16 | 17 | export const dateUtil = dayjs; 18 | -------------------------------------------------------------------------------- /server/app/common/model/upload/FileModel.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 20 | -------------------------------------------------------------------------------- /console/src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /console/src/views/system/storage/group/formSchemas.ts: -------------------------------------------------------------------------------- 1 | import type { FormSchema } from '@/components/business/schema-form/'; 2 | 3 | export const formSchemas: FormSchema[] = [ 4 | { 5 | field: 'name', 6 | component: 'Input', 7 | label: '分组名称', 8 | rules: [{ required: true }], 9 | colProps: { 10 | span: 24, 11 | }, 12 | }, 13 | { 14 | field: 'sort', 15 | component: 'InputNumber', 16 | label: '排序', 17 | rules: [{ required: true }], 18 | colProps: { 19 | span: 24, 20 | }, 21 | }, 22 | 23 | ]; -------------------------------------------------------------------------------- /console/.env: -------------------------------------------------------------------------------- 1 | # 项目名称 2 | VITE_APP_TITLE = EvoAdmin 3 | 4 | # 公共基础路径, 详见: https://cn.vitejs.dev/guide/build.html#public-base-path 5 | VITE_BASE_API_URL = '/api' 6 | 7 | # 资源域名(头部) 8 | VITE_DOMAIN_URL = 'http://127.0.0.1:19878' 9 | 10 | # 图片类型 11 | VITE_IMAGE_TYPE = '.jpg,.jpeg,.png,.gif,.webp' 12 | 13 | # 上传的视频类型 14 | VITE_VIDEO_TYPE = 'video/mp4,video/avi,video/wmv,video/flv,video/mkv' 15 | 16 | # 上传的文件类型 17 | VITE_FILE_TYPE = '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf,.zip,.rar,.7z' 18 | 19 | # 高德地图的key 20 | VITE_AMAP_KEY = '' 21 | 22 | # 高德地图安全密钥 23 | VITE_AMAP_SECRET_KEY = '' 24 | 25 | # 切片上传分片大小 单位 MB 26 | VITE_CHUNK_SIZE = 5 -------------------------------------------------------------------------------- /console/src/hooks/useSortable.ts: -------------------------------------------------------------------------------- 1 | import { nextTick, unref } from 'vue'; 2 | import type { Ref } from 'vue'; 3 | import type { Options } from 'sortablejs'; 4 | 5 | export function useSortable(el: HTMLElement | Ref, options?: Options) { 6 | function initSortable() { 7 | nextTick(async () => { 8 | if (!el) return; 9 | 10 | const Sortable = (await import('sortablejs')).default; 11 | Sortable.create(unref(el), { 12 | animation: 500, 13 | delay: 400, 14 | delayOnTouchOnly: true, 15 | ...options, 16 | }); 17 | }); 18 | } 19 | 20 | return { initSortable }; 21 | } 22 | -------------------------------------------------------------------------------- /console/src/components/business/schema-form/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | import type { FormState } from './useFormState'; 2 | import type { FormEvents } from './useFormEvents'; 3 | import type { FormMethods } from './useFormMethods'; 4 | import type { SchemaFormEmitFn } from '../schema-form'; 5 | 6 | export * from './useForm'; 7 | export * from './useFormState'; 8 | export * from './useFormContext'; 9 | export * from './useFormEvents'; 10 | export * from './useFormMethods'; 11 | export * from './useLabelWidth'; 12 | export * from './useAdvanced'; 13 | 14 | export type SchemaFormType = FormState & FormEvents & FormMethods & { emit: SchemaFormEmitFn }; 15 | -------------------------------------------------------------------------------- /console/src/components/core/basic-arrow/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 18 | 19 | 25 | -------------------------------------------------------------------------------- /server/config/server.php: -------------------------------------------------------------------------------- 1 | 'http://0.0.0.0:19878', 5 | 'transport' => 'tcp', 6 | 'context' => [], 7 | 'name' => 'EvoAdmin', 8 | 'count' => cpu_count(), 9 | 'user' => '', 10 | 'group' => '', 11 | 'reusePort' => false, 12 | 'event_loop' => '', 13 | 'stop_timeout' => 2, 14 | 'pid_file' => runtime_path() . '/webman.pid', 15 | 'status_file' => runtime_path() . '/webman.status', 16 | 'stdout_file' => runtime_path() . '/logs/' . date('Y-m-d') . 'stdout.log', 17 | 'log_file' => runtime_path() . '/logs/workerman.log', 18 | 'max_package_size' => 10 * 1024 * 1024 19 | ]; 20 | -------------------------------------------------------------------------------- /console/src/views/demos/editor/index.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /server/config/log.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'handlers' => [ 6 | [ 7 | 'class' => Monolog\Handler\RotatingFileHandler::class, 8 | 'constructor' => [ 9 | runtime_path() . '/logs/webman.log', 10 | 7, //$maxFiles 11 | Monolog\Logger::DEBUG, 12 | ], 13 | 'formatter' => [ 14 | 'class' => Monolog\Formatter\LineFormatter::class, 15 | 'constructor' => [null, 'Y-m-d H:i:s', true,true], 16 | ], 17 | ] 18 | ], 19 | ], 20 | ]; 21 | -------------------------------------------------------------------------------- /console/src/components/business/dynamic-table/src/components/table-settings/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | -------------------------------------------------------------------------------- /server/support/Request.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace support; 16 | 17 | /** 18 | * Class Request 19 | * @package support 20 | */ 21 | class Request extends \Webman\Http\Request 22 | { 23 | 24 | } -------------------------------------------------------------------------------- /server/support/Response.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright walkor 11 | * @link http://www.workerman.net/ 12 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 13 | */ 14 | 15 | namespace support; 16 | 17 | /** 18 | * Class Response 19 | * @package support 20 | */ 21 | class Response extends \Webman\Http\Response 22 | { 23 | 24 | } -------------------------------------------------------------------------------- /console/src/enums/breakpointEnum.ts: -------------------------------------------------------------------------------- 1 | export enum sizeEnum { 2 | XS = 'XS', 3 | SM = 'SM', 4 | MD = 'MD', 5 | LG = 'LG', 6 | XL = 'XL', 7 | XXL = 'XXL', 8 | } 9 | 10 | export enum screenEnum { 11 | XS = 480, 12 | SM = 576, 13 | MD = 768, 14 | LG = 992, 15 | XL = 1200, 16 | XXL = 1600, 17 | } 18 | 19 | const screenMap = new Map(); 20 | 21 | screenMap.set(sizeEnum.XS, screenEnum.XS); 22 | screenMap.set(sizeEnum.SM, screenEnum.SM); 23 | screenMap.set(sizeEnum.MD, screenEnum.MD); 24 | screenMap.set(sizeEnum.LG, screenEnum.LG); 25 | screenMap.set(sizeEnum.XL, screenEnum.XL); 26 | screenMap.set(sizeEnum.XXL, screenEnum.XXL); 27 | 28 | export { screenMap }; 29 | -------------------------------------------------------------------------------- /console/src/components/core/icon/src/props.ts: -------------------------------------------------------------------------------- 1 | import type { DefaultIconsType } from './icons.data'; 2 | 3 | export const svgIconProps = { 4 | prefix: { 5 | type: String, 6 | default: 'svg-icon', 7 | }, 8 | name: { 9 | type: String, 10 | required: true, 11 | }, 12 | size: { 13 | type: [Number, String], 14 | default: 16, 15 | }, 16 | }; 17 | 18 | export const iconPickerProps = { 19 | value: { 20 | type: String as PropType, 21 | }, 22 | placeholder: String, 23 | }; 24 | 25 | export type IconProps = { 26 | type?: 'svg' | 'iconify' | 'icon-font'; 27 | icon: DefaultIconsType | string; 28 | color?: string; 29 | size?: string | number; 30 | }; 31 | -------------------------------------------------------------------------------- /server/app/middleware/ActionMiddleware.php: -------------------------------------------------------------------------------- 1 | >, 7 | default: () => ({}), 8 | }, 9 | schema: { 10 | type: Object as PropType, 11 | default: () => ({}), 12 | }, 13 | // 动态表格实例 14 | tableInstance: { 15 | type: Object as PropType, 16 | }, 17 | // 动态表格rowKey 18 | tableRowKey: { 19 | type: [String, Number] as PropType, 20 | }, 21 | }; 22 | 23 | export type SchemaFormItemProps = typeof schemaFormItemProps; 24 | -------------------------------------------------------------------------------- /console/src/utils/awaitTo.ts: -------------------------------------------------------------------------------- 1 | // reference https://github.com/scopsy/await-to-js 2 | 3 | /** 4 | * @param { Promise } promise 5 | * @param { Object= } errorExt - Additional Information you can pass to the err object 6 | * @return { Promise } 7 | */ 8 | export function to( 9 | promise: Promise, 10 | errorExt?: object, 11 | ): Promise<[U, undefined] | [null, T]> { 12 | return promise 13 | .then<[null, T]>((data: T) => [null, data]) 14 | .catch<[U, undefined]>((err: U) => { 15 | if (errorExt) { 16 | const parsedError = Object.assign({}, err, errorExt); 17 | return [parsedError, undefined]; 18 | } 19 | 20 | return [err, undefined]; 21 | }); 22 | } 23 | 24 | export default to; 25 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/vue/DynamicTable/function.stub: -------------------------------------------------------------------------------- 1 | // 添加和编辑方法 2 | const openMenuModal = async (record: Partial) => { 3 | const [formRef] = await showModal({ 4 | modalProps: { 5 | title: `${record.{PK} ? '编辑' : '新增'}操作`, 6 | width: 700, 7 | onFinish: async (values) => { 8 | if (record.{PK}) { 9 | values.{PK} = record.{PK}; 10 | await Api.update(values); 11 | } else { 12 | await Api.create(values); 13 | } 14 | dynamicTableInstance.reload(); 15 | }, 16 | }, 17 | formProps: { 18 | labelWidth: 100, 19 | schemas: formSchemas, 20 | }, 21 | }); 22 | formRef?.setFieldsValue({ 23 | ...record 24 | }); 25 | }; -------------------------------------------------------------------------------- /console/src/hooks/useModal/types.ts: -------------------------------------------------------------------------------- 1 | import type { ModalProps } from 'ant-design-vue'; 2 | 3 | // 普通模态框 4 | export interface HookModalProps extends Partial { 5 | /** 当前模态框是否处于App.vue上下文中 */ 6 | isAppChild?: boolean; 7 | content?: string | JSX.Element | (() => JSX.Element); 8 | closeModal?: () => void; 9 | } 10 | 11 | // 表单模态框 12 | export interface FormModalProps extends HookModalProps { 13 | /** 14 | * 接受返回一个boolean,返回 true 会关掉这个弹窗 15 | * 16 | * @name 表单结束后调用 17 | */ 18 | onFinish?: (formData: Objectable) => Promise; 19 | /** 20 | * 接受返回一个boolean,返回 true 会关掉这个弹窗 21 | * 22 | * @name 表单验证失败时调用 23 | */ 24 | onFail?: (formData: Objectable) => any; 25 | } 26 | -------------------------------------------------------------------------------- /server/app/generate/service/stub/php/logic/detailLogic.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * {NOTES}详情 4 | * @param array $params 5 | * @return array 6 | * @throws RespBusinessException 7 | * @date {DATE} 8 | */ 9 | public static function handleDetail(array $params): array 10 | { 11 | try { 12 | $detail = {UPPER_CAMEL_NAME}Model::query()->where('{PK}', $params['{WHERE_PK}'])->select({FIELDS})->first(); 13 | if(is_null($detail)){ 14 | // TODO 抛出异常(直接返回,不经过异常) 15 | throw new \Exception('数据不存在'); 16 | } 17 | return $detail->toArray(); 18 | } catch (\Exception $e) { 19 | throw new RespBusinessException('查询数据详情异常'); 20 | } 21 | } -------------------------------------------------------------------------------- /console/src/router/asyncModules/index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | type ImportVueFileType = typeof import('*.vue'); 3 | type ImportVueFileFnType = () => Promise; 4 | 5 | // auto load 6 | const modulesFiles = import.meta.glob('../../views/**/*.vue'); 7 | // console.log('modulesFiles', modulesFiles); 8 | 9 | // generate components map 10 | export const asyncRoutes = Object.entries(modulesFiles).reduce((routes, [url, importFn]) => { 11 | if (!/\/(views\/login|components)\//.test(url)) { 12 | const path = url.replace('../../views/', '').replace('.vue', ''); 13 | routes[path] = importFn; 14 | } 15 | 16 | return routes; 17 | }, {} as Recordable); 18 | 19 | // console.log('asyncRoutes', asyncRoutes); 20 | -------------------------------------------------------------------------------- /server/config/database.php: -------------------------------------------------------------------------------- 1 | 'mysql', 4 | 'connections' => [ 5 | 'mysql' => [ 6 | 'driver' => 'mysql', 7 | 'host' => '127.0.0.1', 8 | 'port' => 3306, 9 | 'database' => 'evo_php_admin', 10 | 'username' => 'root', 11 | 'password' => '123456', 12 | 'unix_socket' => '', 13 | 'charset' => 'utf8mb4', 14 | 'collation' => 'utf8mb4_0900_ai_ci', 15 | 'prefix' => 'evo_', 16 | 'strict' => true, 17 | 'engine' => null, 18 | 'options' => [ 19 | \PDO::ATTR_TIMEOUT => 3 20 | ] 21 | ], 22 | ], 23 | ]; -------------------------------------------------------------------------------- /console/src/layout/logo/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 15 | 16 | 36 | -------------------------------------------------------------------------------- /console/src/layout/header/components/fullscreen/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 24 | -------------------------------------------------------------------------------- /console/src/views/error/404.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 20 | 21 | 31 | -------------------------------------------------------------------------------- /console/unocss.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | transformerVariantGroup, 3 | transformerDirectives, 4 | presetAttributify, 5 | defineConfig, 6 | presetMini, 7 | presetUno, 8 | } from 'unocss'; 9 | 10 | // https://github.com/unocss/unocss#readme 11 | export default defineConfig({ 12 | presets: [ 13 | presetMini({ dark: 'class' }), 14 | // https://unocss.dev/presets/attributify#properties-conflicts 15 | presetAttributify({ prefix: 'un-', prefixedOnly: true }), 16 | presetUno(), 17 | ], 18 | transformers: [transformerDirectives(), transformerVariantGroup()], 19 | shortcuts: { 20 | 'wh-full': 'w-full h-full', 21 | 'flex-ac': 'flex justify-around items-center', 22 | 'flex-bc': 'flex justify-between items-center', 23 | }, 24 | theme: {}, 25 | }); 26 | -------------------------------------------------------------------------------- /console/src/enums/httpEnum.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description: 请求结果集 3 | */ 4 | export enum ResultEnum { 5 | SUCCESS = 200, 6 | ERROR = -1, 7 | TIMEOUT = 10042, 8 | TYPE = 'success', 9 | } 10 | 11 | /** 12 | * @description: 请求方法 13 | */ 14 | export enum RequestEnum { 15 | GET = 'GET', 16 | POST = 'POST', 17 | PATCH = 'PATCH', 18 | PUT = 'PUT', 19 | DELETE = 'DELETE', 20 | } 21 | 22 | /** 23 | * @description: 常用的contentTyp类型 24 | */ 25 | export enum ContentTypeEnum { 26 | // json 27 | JSON = 'application/json;charset=UTF-8', 28 | // json 29 | TEXT = 'text/plain;charset=UTF-8', 30 | // form-data 一般配合qs 31 | FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8', 32 | // form-data 上传 33 | FORM_DATA = 'multipart/form-data;charset=UTF-8', 34 | } 35 | -------------------------------------------------------------------------------- /console/types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare interface Fn { 2 | (...arg: T[]): R; 3 | } 4 | 5 | declare interface PromiseFn { 6 | (...arg: T[]): Promise; 7 | } 8 | 9 | declare type RefType = T | null; 10 | 11 | declare type LabelValueOptions = { 12 | label: string; 13 | value: any; 14 | [key: string]: string | number | boolean; 15 | }[]; 16 | 17 | declare type EmitType = (event: string, ...args: any[]) => void; 18 | 19 | declare type TargetContext = '_self' | '_blank'; 20 | 21 | declare interface ComponentElRef { 22 | $el: T; 23 | } 24 | 25 | declare type ComponentRef = ComponentElRef | null; 26 | 27 | declare type ElRef = Nullable; 28 | -------------------------------------------------------------------------------- /server/app/common/model/BaseModel.php: -------------------------------------------------------------------------------- 1 | format('Y-m-d H:i:s'); 19 | // } 20 | 21 | public $timestamps = FALSE; 22 | 23 | 24 | /** 25 | * 检查条件是否存在 26 | * @param BaseModel $model 27 | * @param array $where 28 | * @return bool 29 | */ 30 | public static function checkExists(BaseModel $model, array $where): bool 31 | { 32 | return $model::query()->where($where)->exists(); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /console/src/components/business/dynamic-table/src/components/table-settings/search-setting.vue: -------------------------------------------------------------------------------- 1 | 11 | 24 | -------------------------------------------------------------------------------- /console/types/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface ImportMetaEnv { 4 | /** 网站标题 */ 5 | readonly VITE_APP_TITLE: string; 6 | /** 网站部署的目录 */ 7 | readonly VITE_BASE_URL: string; 8 | /** API 接口路径 */ 9 | readonly VITE_BASE_API_URL: string; 10 | /** 切片上传分片大小 */ 11 | readonly VITE_CHUNK_SIZE: number; 12 | /** 静态资源路径 */ 13 | readonly VITE_DOMAIN_URL: string; 14 | /** 上传的图片类型 */ 15 | readonly VITE_IMAGE_TYPE: string; 16 | /** 上传的视频类型 */ 17 | readonly VITE_VIDEO_TYPE: string; 18 | /** 上传的文件类型 */ 19 | readonly VITE_FILE_TYPE: string; 20 | /** 高德地图的key */ 21 | readonly VITE_AMAP_KEY: string; 22 | /** 高德地图安全密钥 */ 23 | readonly VITE_AMAP_SECRET_KEY: string; 24 | } 25 | 26 | interface ImportMeta { 27 | readonly env: ImportMetaEnv; 28 | } 29 | -------------------------------------------------------------------------------- /console/src/api/backend/logRequest.ts: -------------------------------------------------------------------------------- 1 | import {request, type RequestOptions} from '@/utils/request'; 2 | 3 | /** 登录日志 列表方法 POST /sys/log/login/list */ 4 | export async function list(body: any, options?: RequestOptions) { 5 | return request('/system/log/request/list', { 6 | method: 'POST', 7 | headers: { 8 | 'Content-Type': 'application/json', 9 | }, 10 | data: body, 11 | ...(options || {}), 12 | }); 13 | } 14 | 15 | 16 | /** 登录日志 详情方法 POST /sys/log/login/detail */ 17 | export async function detail(body: any, options?: RequestOptions) { 18 | return request('/system/log/request/detail', { 19 | method: 'POST', 20 | headers: { 21 | 'Content-Type': 'application/json', 22 | }, 23 | data: body, 24 | ...(options), 25 | }); 26 | } -------------------------------------------------------------------------------- /console/src/components/core/button/button.ts: -------------------------------------------------------------------------------- 1 | import buttonProps from 'ant-design-vue/es/button/buttonTypes'; 2 | import { theme } from 'ant-design-vue'; 3 | import type { ButtonType as AButtonType } from 'ant-design-vue/es/button/buttonTypes'; 4 | import type { ExtractPropTypes } from 'vue'; 5 | 6 | const { defaultSeed } = theme; 7 | 8 | export declare type ButtonProps = Partial>; 9 | 10 | export type ButtonType = AButtonType | 'warning' | 'success' | 'error'; 11 | 12 | /** 这里自定义颜色 */ 13 | export const buttonColorPrimary = { 14 | success: defaultSeed.colorSuccess, 15 | warning: defaultSeed.colorWarning, 16 | error: defaultSeed.colorError, 17 | } as const; 18 | 19 | export const aButtonTypes = ['default', 'primary', 'ghost', 'dashed', 'link', 'text']; 20 | 21 | export type { AButtonType }; 22 | export { buttonProps }; 23 | -------------------------------------------------------------------------------- /console/src/components/core/pro-config-provider/index.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 27 | -------------------------------------------------------------------------------- /console/src/components/core/iframe-page/index.vue: -------------------------------------------------------------------------------- 1 |