Showing preview only (3,228K chars total). Download the full file or copy to clipboard to get everything.
Repository: flipped-aurora/gin-vue-admin
Branch: main
Commit: a75ab546ee06
Files: 646
Total size: 3.0 MB
Directory structure:
gitextract_u70pmzr2/
├── .aone_copilot/
│ └── rules/
│ └── project_rules.md
├── .claude/
│ └── rules/
│ └── project_rules.md
├── .codex/
│ └── rules/
│ └── project_rules.md
├── .cursor/
│ └── rules/
│ └── project_rules.md
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yaml
│ │ ├── config.yml
│ │ └── feature_request.yaml
│ └── workflows/
│ └── ci.yaml
├── .gitignore
├── .trae/
│ └── rules/
│ └── project_rules.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README-en.md
├── README.md
├── SECURITY.md
├── deploy/
│ ├── docker/
│ │ ├── Dockerfile
│ │ └── entrypoint.sh
│ ├── docker-compose/
│ │ └── docker-compose.yaml
│ └── kubernetes/
│ ├── server/
│ │ ├── gva-server-configmap.yaml
│ │ ├── gva-server-deployment.yaml
│ │ └── gva-server-service.yaml
│ └── web/
│ ├── gva-web-configmap.yaml
│ ├── gva-web-deploymemt.yaml
│ ├── gva-web-ingress.yaml
│ └── gva-web-service.yaml
├── gin-vue-admin.code-workspace
├── server/
│ ├── Dockerfile
│ ├── README.md
│ ├── api/
│ │ └── v1/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── auto_code_history.go
│ │ ├── auto_code_mcp.go
│ │ ├── auto_code_package.go
│ │ ├── auto_code_plugin.go
│ │ ├── auto_code_template.go
│ │ ├── enter.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code.go
│ │ ├── sys_captcha.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_jwt_blacklist.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── config/
│ │ ├── auto_code.go
│ │ ├── captcha.go
│ │ ├── config.go
│ │ ├── cors.go
│ │ ├── db_list.go
│ │ ├── disk.go
│ │ ├── email.go
│ │ ├── excel.go
│ │ ├── gorm_mssql.go
│ │ ├── gorm_mysql.go
│ │ ├── gorm_oracle.go
│ │ ├── gorm_pgsql.go
│ │ ├── gorm_sqlite.go
│ │ ├── jwt.go
│ │ ├── mcp.go
│ │ ├── mongo.go
│ │ ├── oss_aliyun.go
│ │ ├── oss_aws.go
│ │ ├── oss_cloudflare.go
│ │ ├── oss_huawei.go
│ │ ├── oss_local.go
│ │ ├── oss_minio.go
│ │ ├── oss_qiniu.go
│ │ ├── oss_tencent.go
│ │ ├── redis.go
│ │ ├── system.go
│ │ └── zap.go
│ ├── config.docker.yaml
│ ├── config.yaml
│ ├── core/
│ │ ├── internal/
│ │ │ ├── constant.go
│ │ │ ├── cutter.go
│ │ │ └── zap_core.go
│ │ ├── server.go
│ │ ├── server_run.go
│ │ ├── viper.go
│ │ └── zap.go
│ ├── docs/
│ │ ├── docs.go
│ │ ├── swagger.json
│ │ └── swagger.yaml
│ ├── global/
│ │ ├── global.go
│ │ ├── model.go
│ │ └── version.go
│ ├── go.mod
│ ├── go.sum
│ ├── initialize/
│ │ ├── db_list.go
│ │ ├── ensure_tables.go
│ │ ├── gorm.go
│ │ ├── gorm_biz.go
│ │ ├── gorm_mssql.go
│ │ ├── gorm_mysql.go
│ │ ├── gorm_oracle.go
│ │ ├── gorm_pgsql.go
│ │ ├── gorm_sqlite.go
│ │ ├── init.go
│ │ ├── internal/
│ │ │ ├── gorm.go
│ │ │ ├── gorm_logger_writer.go
│ │ │ └── mongo.go
│ │ ├── mcp.go
│ │ ├── mongo.go
│ │ ├── other.go
│ │ ├── plugin.go
│ │ ├── plugin_biz_v1.go
│ │ ├── plugin_biz_v2.go
│ │ ├── redis.go
│ │ ├── register_init.go
│ │ ├── reload.go
│ │ ├── router.go
│ │ ├── router_biz.go
│ │ ├── timer.go
│ │ └── validator.go
│ ├── main.go
│ ├── mcp/
│ │ ├── api_creator.go
│ │ ├── api_lister.go
│ │ ├── client/
│ │ │ ├── client.go
│ │ │ └── client_test.go
│ │ ├── dictionary_generator.go
│ │ ├── dictionary_query.go
│ │ ├── enter.go
│ │ ├── gva_analyze.go
│ │ ├── gva_execute.go
│ │ ├── gva_review.go
│ │ ├── menu_creator.go
│ │ ├── menu_lister.go
│ │ └── requirement_analyzer.go
│ ├── middleware/
│ │ ├── casbin_rbac.go
│ │ ├── cors.go
│ │ ├── email.go
│ │ ├── error.go
│ │ ├── jwt.go
│ │ ├── limit_ip.go
│ │ ├── loadtls.go
│ │ ├── logger.go
│ │ ├── operation.go
│ │ └── timeout.go
│ ├── model/
│ │ ├── common/
│ │ │ ├── basetypes.go
│ │ │ ├── clearDB.go
│ │ │ ├── request/
│ │ │ │ └── common.go
│ │ │ └── response/
│ │ │ ├── common.go
│ │ │ └── response.go
│ │ ├── example/
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ ├── exa_file_upload_download.go
│ │ │ ├── request/
│ │ │ │ └── exa_file_upload_and_downloads.go
│ │ │ └── response/
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── request/
│ │ │ ├── jwt.go
│ │ │ ├── sys_api.go
│ │ │ ├── sys_api_token.go
│ │ │ ├── sys_authority_btn.go
│ │ │ ├── sys_auto_code.go
│ │ │ ├── sys_auto_code_mcp.go
│ │ │ ├── sys_auto_code_package.go
│ │ │ ├── sys_auto_history.go
│ │ │ ├── sys_casbin.go
│ │ │ ├── sys_dictionary.go
│ │ │ ├── sys_dictionary_detail.go
│ │ │ ├── sys_error.go
│ │ │ ├── sys_export_template.go
│ │ │ ├── sys_init.go
│ │ │ ├── sys_login_log.go
│ │ │ ├── sys_menu.go
│ │ │ ├── sys_operation_record.go
│ │ │ ├── sys_params.go
│ │ │ ├── sys_skills.go
│ │ │ ├── sys_user.go
│ │ │ └── sys_version.go
│ │ ├── response/
│ │ │ ├── sys_api.go
│ │ │ ├── sys_authority.go
│ │ │ ├── sys_authority_btn.go
│ │ │ ├── sys_auto_code.go
│ │ │ ├── sys_captcha.go
│ │ │ ├── sys_casbin.go
│ │ │ ├── sys_menu.go
│ │ │ ├── sys_system.go
│ │ │ ├── sys_user.go
│ │ │ └── sys_version.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_authority_menu.go
│ │ ├── sys_auto_code_history.go
│ │ ├── sys_auto_code_package.go
│ │ ├── sys_base_menu.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_jwt_blacklist.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu_btn.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ ├── sys_user_authority.go
│ │ └── sys_version.go
│ ├── plugin/
│ │ ├── announcement/
│ │ │ ├── api/
│ │ │ │ ├── enter.go
│ │ │ │ └── info.go
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── gen/
│ │ │ │ └── gen.go
│ │ │ ├── initialize/
│ │ │ │ ├── api.go
│ │ │ │ ├── dictionary.go
│ │ │ │ ├── gorm.go
│ │ │ │ ├── menu.go
│ │ │ │ ├── router.go
│ │ │ │ └── viper.go
│ │ │ ├── model/
│ │ │ │ ├── info.go
│ │ │ │ └── request/
│ │ │ │ └── info.go
│ │ │ ├── plugin/
│ │ │ │ └── plugin.go
│ │ │ ├── plugin.go
│ │ │ ├── router/
│ │ │ │ ├── enter.go
│ │ │ │ └── info.go
│ │ │ └── service/
│ │ │ ├── enter.go
│ │ │ └── info.go
│ │ ├── email/
│ │ │ ├── README.MD
│ │ │ ├── api/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ ├── config/
│ │ │ │ └── email.go
│ │ │ ├── global/
│ │ │ │ └── gloabl.go
│ │ │ ├── main.go
│ │ │ ├── model/
│ │ │ │ └── response/
│ │ │ │ └── email.go
│ │ │ ├── router/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ ├── service/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ └── utils/
│ │ │ └── email.go
│ │ ├── plugin-tool/
│ │ │ └── utils/
│ │ │ └── check.go
│ │ └── register.go
│ ├── resource/
│ │ ├── function/
│ │ │ ├── api.go.tpl
│ │ │ ├── api.js.tpl
│ │ │ └── server.go.tpl
│ │ ├── mcp/
│ │ │ └── tools.tpl
│ │ ├── package/
│ │ │ ├── readme.txt.tpl
│ │ │ ├── server/
│ │ │ │ ├── api/
│ │ │ │ │ ├── api.go.tpl
│ │ │ │ │ └── enter.go.tpl
│ │ │ │ ├── model/
│ │ │ │ │ ├── model.go.tpl
│ │ │ │ │ └── request/
│ │ │ │ │ └── request.go.tpl
│ │ │ │ ├── router/
│ │ │ │ │ ├── enter.go.tpl
│ │ │ │ │ └── router.go.tpl
│ │ │ │ └── service/
│ │ │ │ ├── enter.go.tpl
│ │ │ │ └── service.go.tpl
│ │ │ └── web/
│ │ │ ├── api/
│ │ │ │ └── api.js.tpl
│ │ │ └── view/
│ │ │ ├── form.vue.tpl
│ │ │ └── table.vue.tpl
│ │ └── plugin/
│ │ ├── server/
│ │ │ ├── api/
│ │ │ │ ├── api.go.tpl
│ │ │ │ └── enter.go.tpl
│ │ │ ├── config/
│ │ │ │ └── config.go.tpl
│ │ │ ├── gen/
│ │ │ │ └── gen.go.tpl
│ │ │ ├── initialize/
│ │ │ │ ├── api.go.tpl
│ │ │ │ ├── dictionary.go.tpl
│ │ │ │ ├── gorm.go.tpl
│ │ │ │ ├── menu.go.tpl
│ │ │ │ ├── router.go.tpl
│ │ │ │ └── viper.go.tpl
│ │ │ ├── model/
│ │ │ │ ├── model.go.tpl
│ │ │ │ └── request/
│ │ │ │ └── request.go.tpl
│ │ │ ├── plugin/
│ │ │ │ └── plugin.go.tpl
│ │ │ ├── plugin.go.tpl
│ │ │ ├── router/
│ │ │ │ ├── enter.go.tpl
│ │ │ │ └── router.go.tpl
│ │ │ └── service/
│ │ │ ├── enter.go.tpl
│ │ │ └── service.go.tpl
│ │ └── web/
│ │ ├── api/
│ │ │ └── api.js.tpl
│ │ ├── form/
│ │ │ └── form.vue.tpl
│ │ └── view/
│ │ └── view.vue.tpl
│ ├── router/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_and_download.go
│ │ └── system/
│ │ ├── enter.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code.go
│ │ ├── sys_auto_code_history.go
│ │ ├── sys_base.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_jwt.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── service/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── auto_code_history.go
│ │ ├── auto_code_llm.go
│ │ ├── auto_code_mcp.go
│ │ ├── auto_code_package.go
│ │ ├── auto_code_package_test.go
│ │ ├── auto_code_plugin.go
│ │ ├── auto_code_template.go
│ │ ├── auto_code_template_test.go
│ │ ├── enter.go
│ │ ├── jwt_black_list.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code_interface.go
│ │ ├── sys_auto_code_mssql.go
│ │ ├── sys_auto_code_mysql.go
│ │ ├── sys_auto_code_oracle.go
│ │ ├── sys_auto_code_pgsql.go
│ │ ├── sys_auto_code_sqlite.go
│ │ ├── sys_base_menu.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_initdb_mssql.go
│ │ ├── sys_initdb_mysql.go
│ │ ├── sys_initdb_pgsql.go
│ │ ├── sys_initdb_sqlite.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── source/
│ │ ├── example/
│ │ │ └── file_upload_download.go
│ │ └── system/
│ │ ├── api.go
│ │ ├── api_ignore.go
│ │ ├── authorities_menus.go
│ │ ├── authority.go
│ │ ├── casbin.go
│ │ ├── dictionary.go
│ │ ├── dictionary_detail.go
│ │ ├── excel_template.go
│ │ ├── menu.go
│ │ └── user.go
│ ├── task/
│ │ └── clearTable.go
│ └── utils/
│ ├── ast/
│ │ ├── ast.go
│ │ ├── ast_auto_enter.go
│ │ ├── ast_enter.go
│ │ ├── ast_gorm.go
│ │ ├── ast_init_test.go
│ │ ├── ast_rollback.go
│ │ ├── ast_router.go
│ │ ├── ast_test.go
│ │ ├── ast_type.go
│ │ ├── extract_func.go
│ │ ├── import.go
│ │ ├── interfaces.go
│ │ ├── interfaces_base.go
│ │ ├── package_enter.go
│ │ ├── package_enter_test.go
│ │ ├── package_initialize_gorm.go
│ │ ├── package_initialize_gorm_test.go
│ │ ├── package_initialize_router.go
│ │ ├── package_initialize_router_test.go
│ │ ├── package_module_enter.go
│ │ ├── package_module_enter_test.go
│ │ ├── plugin_enter.go
│ │ ├── plugin_enter_test.go
│ │ ├── plugin_gen.go
│ │ ├── plugin_gen_test.go
│ │ ├── plugin_initialize_gorm.go
│ │ ├── plugin_initialize_gorm_test.go
│ │ ├── plugin_initialize_router.go
│ │ ├── plugin_initialize_router_test.go
│ │ ├── plugin_initialize_v2.go
│ │ └── plugin_initialize_v2_test.go
│ ├── autocode/
│ │ └── template_funcs.go
│ ├── breakpoint_continue.go
│ ├── captcha/
│ │ └── redis.go
│ ├── casbin_util.go
│ ├── claims.go
│ ├── directory.go
│ ├── fmt_plus.go
│ ├── hash.go
│ ├── human_duration.go
│ ├── human_duration_test.go
│ ├── json.go
│ ├── json_test.go
│ ├── jwt.go
│ ├── plugin/
│ │ ├── plugin.go
│ │ └── v2/
│ │ ├── plugin.go
│ │ └── registry.go
│ ├── request/
│ │ └── http.go
│ ├── server.go
│ ├── stacktrace/
│ │ └── stacktrace.go
│ ├── system_events.go
│ ├── timer/
│ │ ├── timed_task.go
│ │ └── timed_task_test.go
│ ├── upload/
│ │ ├── aliyun_oss.go
│ │ ├── aws_s3.go
│ │ ├── cloudflare_r2.go
│ │ ├── local.go
│ │ ├── minio_oss.go
│ │ ├── obs.go
│ │ ├── qiniu.go
│ │ ├── tencent_cos.go
│ │ └── upload.go
│ ├── validator.go
│ ├── validator_test.go
│ ├── verify.go
│ └── zip.go
└── web/
├── .docker-compose/
│ └── nginx/
│ └── conf.d/
│ ├── my.conf
│ └── nginx.conf
├── .dockerignore
├── .gitignore
├── .prettierrc
├── Dockerfile
├── README.md
├── babel.config.js
├── eslint.config.mjs
├── index.html
├── jsconfig.json
├── limit.js
├── openDocument.js
├── package.json
├── src/
│ ├── App.vue
│ ├── api/
│ │ ├── api.js
│ │ ├── attachmentCategory.js
│ │ ├── authority.js
│ │ ├── authorityBtn.js
│ │ ├── autoCode.js
│ │ ├── breakpoint.js
│ │ ├── casbin.js
│ │ ├── customer.js
│ │ ├── email.js
│ │ ├── exportTemplate.js
│ │ ├── fileUploadAndDownload.js
│ │ ├── github.js
│ │ ├── initdb.js
│ │ ├── jwt.js
│ │ ├── menu.js
│ │ ├── plugin/
│ │ │ └── api.js
│ │ ├── skills.js
│ │ ├── sysApiToken.js
│ │ ├── sysDictionary.js
│ │ ├── sysDictionaryDetail.js
│ │ ├── sysLoginLog.js
│ │ ├── sysOperationRecord.js
│ │ ├── sysParams.js
│ │ ├── system/
│ │ │ └── sysError.js
│ │ ├── system.js
│ │ ├── user.js
│ │ └── version.js
│ ├── components/
│ │ ├── application/
│ │ │ └── index.vue
│ │ ├── arrayCtrl/
│ │ │ └── arrayCtrl.vue
│ │ ├── bottomInfo/
│ │ │ └── bottomInfo.vue
│ │ ├── charts/
│ │ │ └── index.vue
│ │ ├── commandMenu/
│ │ │ └── index.vue
│ │ ├── customPic/
│ │ │ └── index.vue
│ │ ├── errorPreview/
│ │ │ └── index.vue
│ │ ├── exportExcel/
│ │ │ ├── exportExcel.vue
│ │ │ ├── exportTemplate.vue
│ │ │ └── importExcel.vue
│ │ ├── logo/
│ │ │ └── index.vue
│ │ ├── office/
│ │ │ ├── docx.vue
│ │ │ ├── excel.vue
│ │ │ ├── index.vue
│ │ │ └── pdf.vue
│ │ ├── richtext/
│ │ │ ├── rich-edit.vue
│ │ │ └── rich-view.vue
│ │ ├── selectFile/
│ │ │ └── selectFile.vue
│ │ ├── selectImage/
│ │ │ ├── selectComponent.vue
│ │ │ └── selectImage.vue
│ │ ├── svgIcon/
│ │ │ └── svgIcon.vue
│ │ ├── upload/
│ │ │ ├── QR-code.vue
│ │ │ ├── common.vue
│ │ │ ├── cropper.vue
│ │ │ └── image.vue
│ │ └── warningBar/
│ │ └── warningBar.vue
│ ├── core/
│ │ ├── config.js
│ │ ├── error-handel.js
│ │ ├── gin-vue-admin.js
│ │ └── global.js
│ ├── directive/
│ │ ├── auth.js
│ │ └── clickOutSide.js
│ ├── hooks/
│ │ ├── charts.js
│ │ ├── responsive.js
│ │ └── use-windows-resize.js
│ ├── main.js
│ ├── pathInfo.json
│ ├── permission.js
│ ├── pinia/
│ │ ├── index.js
│ │ └── modules/
│ │ ├── app.js
│ │ ├── dictionary.js
│ │ ├── params.js
│ │ ├── router.js
│ │ └── user.js
│ ├── plugin/
│ │ ├── announcement/
│ │ │ ├── api/
│ │ │ │ └── info.js
│ │ │ ├── form/
│ │ │ │ └── info.vue
│ │ │ └── view/
│ │ │ └── info.vue
│ │ └── email/
│ │ ├── api/
│ │ │ └── email.js
│ │ └── view/
│ │ └── index.vue
│ ├── router/
│ │ └── index.js
│ ├── style/
│ │ ├── element/
│ │ │ └── index.scss
│ │ ├── element_visiable.scss
│ │ ├── iconfont.css
│ │ ├── main.scss
│ │ ├── reset.scss
│ │ └── transition.scss
│ ├── utils/
│ │ ├── asyncRouter.js
│ │ ├── btnAuth.js
│ │ ├── bus.js
│ │ ├── closeThisPage.js
│ │ ├── date.js
│ │ ├── dictionary.js
│ │ ├── doc.js
│ │ ├── downloadImg.js
│ │ ├── env.js
│ │ ├── event.js
│ │ ├── fmtRouterTitle.js
│ │ ├── format.js
│ │ ├── image.js
│ │ ├── page.js
│ │ ├── params.js
│ │ ├── request.js
│ │ └── stringFun.js
│ └── view/
│ ├── about/
│ │ └── index.vue
│ ├── dashboard/
│ │ ├── components/
│ │ │ ├── banner.vue
│ │ │ ├── card.vue
│ │ │ ├── charts-content-numbers.vue
│ │ │ ├── charts-people-numbers.vue
│ │ │ ├── charts.vue
│ │ │ ├── index.js
│ │ │ ├── notice.vue
│ │ │ ├── pluginTable.vue
│ │ │ ├── quickLinks.vue
│ │ │ ├── table.vue
│ │ │ └── wiki.vue
│ │ └── index.vue
│ ├── error/
│ │ ├── index.vue
│ │ └── reload.vue
│ ├── example/
│ │ ├── breakpoint/
│ │ │ └── breakpoint.vue
│ │ ├── customer/
│ │ │ └── customer.vue
│ │ ├── index.vue
│ │ └── upload/
│ │ ├── scanUpload.vue
│ │ └── upload.vue
│ ├── init/
│ │ └── index.vue
│ ├── layout/
│ │ ├── aside/
│ │ │ ├── asideComponent/
│ │ │ │ ├── asyncSubmenu.vue
│ │ │ │ ├── index.vue
│ │ │ │ └── menuItem.vue
│ │ │ ├── combinationMode.vue
│ │ │ ├── headMode.vue
│ │ │ ├── index.vue
│ │ │ ├── normalMode.vue
│ │ │ └── sidebarMode.vue
│ │ ├── header/
│ │ │ ├── index.vue
│ │ │ └── tools.vue
│ │ ├── iframe.vue
│ │ ├── index.vue
│ │ ├── screenfull/
│ │ │ └── index.vue
│ │ ├── search/
│ │ │ └── search.vue
│ │ ├── setting/
│ │ │ ├── components/
│ │ │ │ ├── layoutModeCard.vue
│ │ │ │ ├── settingItem.vue
│ │ │ │ ├── themeColorPicker.vue
│ │ │ │ └── themeModeSelector.vue
│ │ │ ├── index.vue
│ │ │ └── modules/
│ │ │ ├── appearance/
│ │ │ │ └── index.vue
│ │ │ ├── general/
│ │ │ │ └── index.vue
│ │ │ └── layout/
│ │ │ └── index.vue
│ │ └── tabs/
│ │ └── index.vue
│ ├── login/
│ │ └── index.vue
│ ├── person/
│ │ └── person.vue
│ ├── routerHolder.vue
│ ├── superAdmin/
│ │ ├── api/
│ │ │ └── api.vue
│ │ ├── authority/
│ │ │ ├── authority.vue
│ │ │ └── components/
│ │ │ ├── apis.vue
│ │ │ ├── datas.vue
│ │ │ └── menus.vue
│ │ ├── dictionary/
│ │ │ ├── sysDictionary.vue
│ │ │ └── sysDictionaryDetail.vue
│ │ ├── index.vue
│ │ ├── menu/
│ │ │ ├── components/
│ │ │ │ └── components-cascader.vue
│ │ │ ├── icon.vue
│ │ │ └── menu.vue
│ │ ├── operation/
│ │ │ └── sysOperationRecord.vue
│ │ ├── params/
│ │ │ └── sysParams.vue
│ │ └── user/
│ │ └── user.vue
│ ├── system/
│ │ └── state.vue
│ └── systemTools/
│ ├── apiToken/
│ │ └── index.vue
│ ├── autoCode/
│ │ ├── component/
│ │ │ ├── fieldDialog.vue
│ │ │ └── previewCodeDialog.vue
│ │ ├── index.vue
│ │ ├── mcp.vue
│ │ ├── mcpTest.vue
│ │ └── picture.vue
│ ├── autoCodeAdmin/
│ │ └── index.vue
│ ├── autoPkg/
│ │ └── autoPkg.vue
│ ├── exportTemplate/
│ │ ├── code.js
│ │ └── exportTemplate.vue
│ ├── formCreate/
│ │ └── index.vue
│ ├── index.vue
│ ├── installPlugin/
│ │ └── index.vue
│ ├── loginLog/
│ │ └── index.vue
│ ├── pubPlug/
│ │ └── pubPlug.vue
│ ├── skills/
│ │ └── index.vue
│ ├── sysError/
│ │ └── sysError.vue
│ ├── system/
│ │ └── system.vue
│ └── version/
│ └── version.vue
├── uno.config.js
├── vite.config.js
└── vitePlugin/
├── componentName/
│ └── index.js
└── secret/
└── index.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .aone_copilot/rules/project_rules.md
================================================
### 功能描述以及必要性描述
---
name: gin-vue-admin
description: |
gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
- Vue 3.5.7 + Composition API
- Vite 6.2.3 构建工具
- Pinia 2.2.2 状态管理
- Element Plus 2.10.2 UI组件库
- UnoCSS 66.4.2 原子化CSS框架
- Vue Router 4.4.3 路由管理
- Axios 1.8.2 HTTP客户端
- ECharts 5.5.1 数据可视化
- @vueuse/core Vue组合式API工具集
后端技术栈:
- Go 1.23 + Gin 1.10.0 Web框架
- GORM 1.25.12 ORM框架
- Casbin 2.103.0 权限管理
- Viper 1.19.0 配置管理
- Zap 1.27.0 日志系统
- Redis 9.7.0 缓存
- JWT 5.2.2 认证授权
- 支持MySQL、PostgreSQL、SQLite、SQL Server、MongoDB多种数据库
- 集成阿里云OSS、AWS S3、MinIO、七牛云、腾讯云COS等云存储服务
核心特性:
- 完整的RBAC权限控制系统
- 代码自动生成功能
- 丰富的中间件支持
- 插件化架构设计
- Swagger API文档
---
#### **角色与目标**
你是一名资深的全栈开发专家,**专精于 `gin-vue-admin` (GVA) 框架的架构与开发范式**,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发**完整、生产级别的全栈功能包或插件**。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
---
### **🚀 重要提示:GVA Helper MCP 支持**
**在开始任何GVA开发工作之前,请务必注意以下重要工作流程:**
1. **MCP支持**: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
2. **GVA Helper**: 通常会有一个名为 "**GVA Helper**" 的MCP助手,专门为GVA框架开发提供支持
3. **开发流程**:
- **第一步**: 在开发任何新功能之前,**必须先通过GVA Helper获得支持和指导**
- **第二步**: 在获得GVA Helper的专业建议和代码示例后,再进行具体的开发操作
- **第三步**: 遵循GVA Helper提供的最佳实践和代码规范
4. **优势**: 通过GVA Helper可以获得:
- 最新的GVA框架特性和最佳实践
- 符合项目规范的代码模板
- 避免常见的开发陷阱和错误
- 确保代码质量和一致性
**请始终记住:GVA Helper → 获得支持 → 开始开发**
---
### **核心开发指令:绝不可违背的原则**
## **项目结构说明**
### **整体架构**
gin-vue-admin 采用前后端分离架构:
- **后端 (server/)**:基于 Go + Gin 的 RESTful API 服务
- **前端 (web/)**:基于 Vue 3 + Vite 的单页面应用
- **部署 (deploy/)**:Docker、Kubernetes 等部署配置
### **后端目录结构 (server/)**
```
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
```
### **前端目录结构 (web/)**
```
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
```
---
#### 后端规则
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的分层架构**:
- **职责单一**: 每个层(Model, Service, API, Router)都有其唯一职责,**严禁跨层调用**。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理`gin.Context`。
- **依赖关系**: 依赖链条必须是单向的:`Router -> API -> Service -> Model`。
2. **`enter.go` 组管理模式**:
- 所有 `api`, `service`, `router` 层都**必须**使用 `enter.go` 文件来创建和暴露各自的 `ApiGroup`, `ServiceGroup`, `RouterGroup`。
- 全局实例变量(如 `service.ServiceGroupApp`)是模块间通信的唯一入口,以此来避免循环引用。
3. **详尽的 Swagger 注释 (API层强制要求)**:
- **每一个**对外暴露的 API 函数都**必须**拥有完整且准确的 Swagger 注释块。这不仅是API文档的来源,也是前后端协作、自动化测试和前端AI分析的基础。注释必须清晰地描述接口的功能、参数和返回值。
4. **统一的响应与错误处理**:
- Service 层函数遇到业务错误时,应返回 `error` 对象。
- API 层负责捕获 Service 层的 `error`,并使用项目统一的 `response` 包(如 `response.OkWithDetailed` 或 `response.FailWithMessage`)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
---
### **各层级代码实现规范**
#### **1. 模型层 (`model/`)**
- **数据模型 (`model/xxx.go`)**:
- 用于定义与数据库表映射的 GORM 结构体。
- 结构体应继承 `global.GVA_MODEL` 以包含 `ID`, `CreatedAt`, `UpdatedAt` 等基础字段。
- 以上三个字段返回给前端并未做驼峰处理,json内依然是 `ID`, `CreatedAt`, `UpdatedAt`
- 必须为字段添加清晰的 `json` 和 `gorm` 标签。
- **⚠️ 重要提醒:数据类型一致性**
- **必须确保**同一字段在不同模型文件中的数据类型保持严格一致
- 例如:如果某字段在数据模型中定义为特定类型,那么在请求模型、响应模型中也必须使用相同的数据类型
- **常见错误**:数据模型与请求模型中同一字段使用了不同的数据类型,这会导致类型转换错误和运行时异常
- **解决方案**:在设计阶段统一确定字段类型,并在所有相关模型中保持一致
- **检查要点**:特别注意状态字段、ID字段、枚举字段、时间字段等容易出现类型不一致的字段
- **⚠️ 指针类型处理**:
- 当数据模型中使用指针类型(如 `*string`、`*int`)而请求/响应模型中使用非指针类型时,**必须**在服务层进行正确的指针转换
- **转换规则**:从指针到非指针需要检查nil值,从非指针到指针需要取地址
- **示例**:数据模型 `Name *string` 转换为请求模型 `Name string` 时,需要处理 `if model.Name != nil { request.Name = *model.Name }`
- **请求模型 (`model/request/xxx.go`)**:
- 用于定义接收前端请求参数的结构体(DTOs)。
- **必须**为字段添加 `json` 和 `form` 标签,以便 Gin 进行参数绑定。
- 对于列表查询请求,应创建一个 `XxxSearch` 结构体,并内嵌通用的 `request.PageInfo` 分页结构体。
#### **2. 服务层 (`service/`)**
- **职责**: 封装所有核心业务逻辑,进行数据库的CRUD操作。**此层不应出现任何与HTTP协议相关的代码(如 `gin.Context`)**。
- **结构**: 在 `service/` 下为每个模块创建 `xxx_service.go` 文件,并在 `service/enter.go` 中注册。
- **函数签名**: 函数应接收具体的业务参数(如 `model.Xxx` 或 `request.XxxSearch`),并返回处理结果和 `error`。
- **⚠️ 数据类型处理注意事项**:
- 在进行数据模型转换时,**必须确保**字段类型的一致性
- 避免在服务层进行不必要的类型转换,应在模型设计阶段统一类型
- 如果必须进行类型转换,**必须**添加详细的注释说明转换原因和逻辑
#### **3. API层 (`api/`)**
- **职责**: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
- **结构**: 在 `api/` 下为每个模块创建 `xxx_api.go` 文件,并在 `api/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `service.ServiceGroupApp` 来调用服务层的方法。
- **Swagger 示例 (必须遵循)**:
Go
```
// CreateXxx 创建XXX
// @Tags XxxModule
// @Summary 创建一个新的XXX
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CreateXxxRequest true "XXX的名称和描述"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /xxx/createXxx [post]
func (a *XxxApi) CreateXxx(c *gin.Context) {
// ...
}
```
#### **4. 路由层 (`router/`)**
- **职责**: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
- **结构**: 在 `router/` 下为每个模块创建 `xxx_router.go` 文件,并在 `router/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `api.ApiGroupApp` 来引用API层的处理函数。
- **路由分组**: 应根据业务需求和权限,合理使用路由组 (`Router.Group()`),并挂载不同的中间件(如鉴权、操作记录等)。
#### **5. 初始化层 (`initialize/`)**
- **职责**: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
- **`gorm.go`**: 实现 `InitializeDB` 函数,**必须**调用 `db.AutoMigrate` 自动迁移本插件所有 `model` 的表结构。
- **`router.go`**: 实现 `InitializeRouter` 函数,**必须**调用 `router.RouterGroupApp` 中本插件路由的初始化方法,注册所有API路由。
- **`menu.go`**: 实现 `InitializeMenu` 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
- viper.go: 加载插件配置文件
- api.go: 注册API到系统
#### **6. 插件入口 (`plugin.go`)
- **职责**: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
- **接口实现**: **必须**定义一个结构体并实现 `system.Plugin` 接口。
- **插件注册**: **必须**调用 ```
func init() {
interfaces.Register(Plugin)
}
```
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
```
2. API入口 (api/enter.go):
```go
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
```
3. Router入口 (router/enter.go):
```go
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
```
### Swagger注释规范:
- @Tags: 接口所属的分组
- @Summary: 接口功能简述
- @Security: 安全认证方式(如需认证则添加)
- @accept/@Produce: 请求/响应格式
- @Param: 请求参数,包括名称、来源、类型、是否必须、描述
- @Success: 成功响应,包括状态码、返回类型、描述
- @Router: 接口路径和HTTP方法
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
---
### **开发工作流**
1. **接收任务**: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
2. **【第一步】模型设计 (奠定基础)**:
- 你的**首要行动**是分析需求,设计并提供 `model` 和 `model/request` 下的所有 Go 结构体定义。这是后续所有开发的基础。
3. **【第二步】自下而上,分层实现**:
- 具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
- 在模型确认后,你将按照 `Service -> API -> Router` 的顺序,逐层生成代码。
- 确保每一层的代码都完整、健壮,并严格遵守上述规范。
4. **【第三步】插件初始化与注册**:
- 在完成核心功能层的代码后,你将生成 `initialize/` 目录下的相关初始化文件(如 `db.go`, `router.go`)以及插件的主入口文件 `plugin.go`。
5. **【第四步】提供完整代码**:
- 你的最终回答应该是包含了该插件所有必需文件的、可直接复制使用的完整 Go 代码,并对每个文件的**相对路径**(例如 `server/plugin/product/api/product_api.go`)和用途进行清晰的说明。
---
## **前端开发规范**
### **角色与目标**
你是一名资深的 Vue.js 前端开发专家,**专精于 `gin-vue-admin` (GVA) 框架的前端架构与开发范式**。
你的核心任务是,根据需求开发**完整、生产级别的前端功能模块或插件**。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
### **核心开发指令:绝不可违背的原则**
#### 前端规则
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的模块化架构**:
- **职责单一**: 每个模块(API、组件、页面、状态)都有其唯一职责,**严禁跨模块直接调用**
- **依赖关系**: 依赖链条必须是单向的:`页面组件 -> API服务 -> 后端接口`
2. **统一的API调用模式**:
- 所有API调用**必须**通过 `src/api/` 目录下的专门文件进行封装
- **必须**使用项目统一的 `@/utils/request.js` 进行HTTP请求
- API函数**必须**包含完整的JSDoc注释,描述接口功能、参数和返回值
3. **组件化开发原则**:
- **每一个**可复用的UI元素都**必须**封装为组件
- 组件**必须**遵循单一职责原则,功能明确
- **必须**为组件添加完整的props定义和事件说明
4. **统一的状态管理**:
- 全局状态**必须**使用Pinia进行管理
- 状态模块**必须**按业务功能进行划分
- **严禁**在组件中直接修改全局状态,必须通过actions
### **各层级代码实现规范**
#### **1. API层 (`src/api/`)**
- **职责**: 封装所有后端API调用,提供统一的接口服务
- **结构**: 按业务模块创建API文件,如 `user.js`、`menu.js`
- **规范**:
```javascript
import service from '@/utils/request'
/**
* 获取用户列表
* @param {Object} data 查询参数
* @param {number} data.page 页码
* @param {number} data.pageSize 每页数量
* @returns {Promise} 用户列表数据
*/
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
```
#### **2. 组件层 (`src/components/`)**
- **职责**: 提供可复用的UI组件
- **结构**: 按功能分类组织,每个组件一个文件夹
- **规范**:
```vue
<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
```
#### **3. 页面层 (`src/view/`)**
- **职责**: 实现具体的业务页面
- **结构**: 按业务模块组织,每个页面一个Vue文件
- **规范**:
- **必须**使用Composition API
- **必须**进行响应式数据管理
- **必须**处理加载状态和错误状态
- **必须**遵循Element Plus组件规范
- **必须**优先使用UnoCSS原子化类名进行样式设计
- **必须**优先el-drawer组件进行编辑,新增,步骤等操作
- **必须**使用el-drawer和el-dialog组件是后一定携带,destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
#### **4. 状态管理 (`src/pinia/`)**
- **职责**: 管理全局状态和业务逻辑
- **结构**: 按业务模块创建store文件
- **规范**:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
const setUserInfo = (val) => {
userInfo.value = val
}
const setToken = (val) => {
token.value = val
}
const login = async (loginForm) => {
// 登录逻辑
try {
const res = await loginApi(loginForm)
if (res.code === 0) {
setUserInfo(res.data.user)
setToken(res.data.token)
return true
}
return false
} catch (error) {
console.error('Login error:', error)
return false
}
}
const logout = async () => {
// 登出逻辑
token.value = ''
userInfo.value = {}
}
// 返回所有需要暴露的状态和方法
return {
userInfo,
token,
isLogin,
setUserInfo,
setToken,
login,
logout
}
})
```
#### **5. 路由管理 (`src/router/`)**
- **职责**: 管理页面路由和权限控制
- **规范**:
- **必须**配置路由元信息
- **必须**实现权限验证
- **必须**支持动态路由
### **前端插件开发规范**
#### **插件目录结构**
```
src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
```
#### **插件开发原则**
1. **独立性**: 插件应该是自包含的,不依赖其他业务模块
2. **可配置性**: 插件应该支持配置化,便于定制
3. **可扩展性**: 插件应该预留扩展接口
4. **一致性**: 插件UI风格应与主系统保持一致
### **代码质量要求**
1. **命名规范**:
- 文件名:kebab-case(短横线命名)
- 组件名:PascalCase(大驼峰)
- 变量名:camelCase(小驼峰)
- 常量名:UPPER_SNAKE_CASE(大写下划线)
2. **注释规范**:
- **必须**为所有API函数添加JSDoc注释
- **必须**为复杂组件添加功能说明
- **必须**为关键业务逻辑添加行内注释
3. **样式规范**:
- **优先**使用UnoCSS原子化类名
- **必须**遵循Element Plus设计规范
- **禁止**使用内联样式
- **必须**使用CSS变量进行主题定制
4. **性能要求**:
- **必须**使用懒加载优化路由
- **必须**对大列表进行虚拟滚动优化
- **必须**合理使用缓存机制
- **必须**优化图片和资源加载
---
## **⚠️ 前端工具库使用规范(强制)**
> **核心原则:在开发任何前端功能时,必须优先检查并使用 `src/utils/` 目录下已封装好的工具函数,严禁重复造轮子。**
`src/utils/` 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
### **工具文件清单**
#### `request.js` — HTTP 请求封装(核心)
- 基于 Axios 封装的统一 HTTP 请求实例,内置全局 Loading 状态管理、JWT Token 自动注入、统一错误处理和响应拦截
- **所有 API 请求必须且只能通过此模块发送,禁止直接使用 axios**
- 用法:`import service from '@/utils/request'`
#### `date.js` — 日期格式化
- 扩展了 `Date.prototype.Format` 方法,支持自定义格式如 `yyyy-MM-dd hh:mm:ss`
- 导出 `formatTimeToStr(times, pattern)` 将时间戳或日期对象格式化为字符串
- **需要格式化日期时,优先使用此工具,禁止自行手写日期格式化逻辑**
- 用法:`import { formatTimeToStr } from '@/utils/date'`
#### `format.js` — 数据展示格式化(综合工具)
- `formatBoolean(bool)` — 将布尔值转为 "是"/"否" 中文展示
- `formatDate(time)` — 将时间转为 `yyyy-MM-dd hh:mm:ss` 格式字符串
- `filterDict(value, options)` — 在字典选项数组(支持多级树形)中根据 value 查找对应的 label
- `filterDataSource(dataSource, value)` — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找
- `getDictFunc(type)` — 异步获取指定类型的字典数据
- `ReturnArrImg(arr)` — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀
- `onDownloadFile(url)` — 触发文件下载
- `setBodyPrimaryColor(primaryColor, darkMode)` — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)
- `CreateUUID()` — 生成 UUID v4 字符串
- `getBaseUrl()` — 获取当前环境的 API BaseURL
- **以上所有格式化场景优先使用此文件中的工具函数**
- 用法:`import { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'`
#### `dictionary.js` — 字典数据获取
- `getDict(type, options)` — 异步获取字典数据,支持 `depth`(深度)和 `value`(指定节点)参数,内置 Pinia store 缓存,避免重复请求
- **凡是需要字典下拉数据、字典树形数据的场景,必须使用此工具**
- 用法:`import { getDict } from '@/utils/dictionary'`
#### `stringFun.js` — 字符串处理
- `toUpperCase(str)` — 首字母转大写
- `toLowerCase(str)` — 首字母转小写
- `toSQLLine(str)` — 驼峰命名转下划线(snake_case),如 `userName` → `user_name`
- `toHump(name)` — 下划线命名转驼峰,如 `user_name` → `userName`
- **进行命名格式转换时必须使用此工具,禁止使用正则手写**
- 用法:`import { toUpperCase, toSQLLine, toHump } from '@/utils/stringFun'`
#### `params.js` — 系统参数获取
- `getParams(key)` — 异步从 Pinia store 中获取系统参数,内置缓存
- **获取系统配置参数时,优先使用此工具**
- 用法:`import { getParams } from '@/utils/params'`
#### `bus.js` — 全局事件总线
- 基于 `mitt` 封装的全局事件总线实例 `emitter`,用于跨组件通信
- **跨层级组件通信优先使用此事件总线,避免滥用 Pinia**
- 用法:`import { emitter } from '@/utils/bus'`
#### `closeThisPage.js` — 关闭当前标签页
- `closeThisPage()` — 触发关闭当前多标签页的操作(通过事件总线发送 `closeThisPage` 事件)
- **在需要程序化关闭当前页面时,必须使用此工具**
- 用法:`import { closeThisPage } from '@/utils/closeThisPage'`
#### `downloadImg.js` — 图片下载
- `downloadImage(imgsrc, name)` — 通过 Canvas 将图片转为 base64 后触发下载,支持跨域
- **需要下载图片时,优先使用此工具**
- 用法:`import { downloadImage } from '@/utils/downloadImg'`
#### `image.js` — 图片压缩
- 导出 `ImageCompress` 类,支持图片等比压缩至指定最大宽高,并可限制文件大小
- **上传图片前需要做压缩处理时,使用此工具**
- 用法:`import ImageCompress from '@/utils/image'`
#### `event.js` — DOM 事件监听管理
- `addEventListen(target, event, handler, capture)` — 安全地添加 DOM 事件监听
- `removeEventListen(target, event, handler, capture)` — 安全地移除 DOM 事件监听
- **手动操作 DOM 事件时,使用此工具以确保安全性**
- 用法:`import { addEventListen, removeEventListen } from '@/utils/event'`
#### `env.js` — 环境判断
- `isDev` — 是否为开发环境(Boolean)
- `isProd` — 是否为生产环境(Boolean)
- **需要区分运行环境时,使用此工具,禁止直接读取 `import.meta.env`**
- 用法:`import { isDev, isProd } from '@/utils/env'`
#### `doc.js` — 外部文档跳转
- `toDoc(url)` — 在新标签页打开指定 URL
- 用法:`import { toDoc } from '@/utils/doc'`
#### `fmtRouterTitle.js` — 路由标题格式化
- `fmtTitle(title, route)` — 解析路由标题中的动态参数插值(如 `${id}` 替换为路由 params/query 值)
- 用法:`import { fmtTitle } from '@/utils/fmtRouterTitle'`
#### `page.js` — 页面标题生成
- `getPageTitle(pageTitle, route)` — 根据页面标题和路由生成完整的浏览器 Tab 标题(格式:`页面名 - 应用名`)
- 用法:`import getPageTitle from '@/utils/page'`
#### `asyncRouter.js` — 异步路由处理
- `asyncRouterHandle(asyncRouter)` — 将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件的 import 函数,支持 `view/` 和 `plugin/` 目录
- **动态路由相关逻辑已由此工具处理,不需要也不应该手动实现**
- 用法:`import { asyncRouterHandle } from '@/utils/asyncRouter'`
#### `btnAuth.js` — 按钮权限
- `useBtnAuth()` — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 `route.meta.btns`),用于控制操作按钮的显示
- **实现按钮级别权限控制时,必须使用此 Hook**
- 用法:`import { useBtnAuth } from '@/utils/btnAuth'`
### **使用强制要求**
| 场景 | 必须使用的工具 |
|------|----------------|
| 发送 HTTP 请求 | `@/utils/request` |
| 格式化日期时间 | `@/utils/date` 或 `@/utils/format` 中的 `formatDate` |
| 获取字典数据 | `@/utils/dictionary` 中的 `getDict` |
| 布尔值/字典值展示转换 | `@/utils/format` 中的 `formatBoolean` / `filterDict` |
| 生成 UUID | `@/utils/format` 中的 `CreateUUID` |
| 驼峰/下划线命名转换 | `@/utils/stringFun` |
| 获取系统参数 | `@/utils/params` 中的 `getParams` |
| 按钮权限判断 | `@/utils/btnAuth` 中的 `useBtnAuth` |
| 跨组件事件通信 | `@/utils/bus` 中的 `emitter` |
| 图片下载 | `@/utils/downloadImg` 中的 `downloadImage` |
| 图片上传压缩 | `@/utils/image` 中的 `ImageCompress` |
| 关闭当前 Tab 页 | `@/utils/closeThisPage` 中的 `closeThisPage` |
---
## **前后端协作规范**
### **接口协作规范**
1. **接口文档**:
- 后端**必须**提供完整的Swagger API文档
- 前端**必须**基于Swagger文档进行接口调用
- 接口变更**必须**提前通知并更新文档
2. **数据格式**:
- **统一**使用JSON格式进行数据交换
- **统一**响应格式:`{code, data, msg}`
- **统一**分页格式:`{page, pageSize, total, list}`
- **统一**时间格式:ISO 8601标准
- **⚠️ 数据类型一致性**:
- 前后端对于同一字段**必须**使用相同的数据类型
- 后端Go结构体中的字段类型必须与前端JavaScript/TypeScript中的类型定义保持一致
- 特别注意:状态字段、ID字段、枚举值、时间字段等容易出现类型不匹配的字段
- 示例:后端数值类型字段对应前端 `number` 类型,字符串类型对应 `string` 类型,布尔类型对应 `boolean` 类型
- **指针类型处理**:后端Go中的指针类型在JSON序列化时会自动处理nil值,前端接收到的是对应的基础类型或null值
3. **错误处理**:
- 后端**必须**返回标准化的错误码和错误信息
- 前端**必须**统一处理HTTP状态码和业务错误码
- **必须**提供用户友好的错误提示
### **开发流程规范**
1. **需求分析阶段**:
- 确定功能需求和接口设计
- 定义数据模型和业务流程
- 制定前后端开发计划
2. **开发阶段**:
- 后端优先开发API接口
- 前端基于Mock数据进行并行开发
- 定期进行接口联调测试
3. **测试阶段**:
- 单元测试:前后端各自负责
- 集成测试:前后端协作完成
- 用户验收测试:产品团队主导
### **版本管理规范**
1. **分支策略**:
- `main`:生产环境分支
- `develop`:开发环境分支
- `feature/*`:功能开发分支
- `hotfix/*`:紧急修复分支
2. **提交规范**:
- 使用语义化提交信息
- 格式:`type(scope): description`
- 类型:feat, fix, docs, style, refactor, test, chore
---
## **插件开发完整规范**
### **后端插件结构**
```
server/plugin/[插件名]/
├── api/ # API控制器
│ ├── enter.go # API组入口
│ └── [模块].go # 具体API实现
├── config/ # 插件配置
│ └── config.go
├── initialize/ # 初始化模块
│ ├── api.go # API注册
│ ├── gorm.go # 数据库初始化
│ ├── menu.go # 菜单初始化
│ ├── router.go # 路由初始化
│ └── viper.go # 配置初始化
├── model/ # 数据模型
│ ├── [模型].go # 数据库模型
│ └── request/ # 请求模型
├── router/ # 路由定义
│ ├── enter.go # 路由组入口
│ └── [模块].go # 具体路由
├── service/ # 业务服务
│ ├── enter.go # 服务组入口
│ └── [模块].go # 具体服务
└── plugin.go # 插件入口
```
### **前端插件结构**
```
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
```
### **插件开发工作流**
1. **【第一步】需求分析**:
- 明确插件功能和业务需求
- 设计数据模型和接口规范
- 规划前端页面和交互流程
2. **【第二步】后端开发**:
- 创建数据模型和请求模型
- 实现服务层业务逻辑
- 开发API控制器和路由
- 编写初始化和配置代码
3. **【第三步】前端开发**:
- 创建API接口封装
- 开发页面组件和表单
- 实现业务逻辑和状态管理
- 集成到主系统菜单
4. **【第四步】测试集成**:
- 单元测试和集成测试
- 前后端联调测试
- 用户体验测试
- 性能和安全测试
### **插件质量标准**
1. **功能完整性**: 插件功能完整,满足业务需求
2. **代码质量**: 代码规范,注释完整,易于维护
3. **数据类型一致性**: 前后端数据模型字段类型保持严格一致,避免类型转换错误
4. **性能表现**: 响应速度快,资源占用合理
5. **用户体验**: 界面友好,操作流畅,错误处理完善
6. **兼容性**: 与主系统兼容,不影响其他功能
7. **安全性**: 数据安全,权限控制,防止安全漏洞
---
### **建议和方案**
基于以上规范,建议AI在开发gin-vue-admin项目时:
1. **严格遵循分层架构**:确保前后端代码都按照规定的层次结构组织
2. **保持代码一致性**:使用统一的命名规范、注释格式和代码风格
3. **注重文档完整性**:确保API文档、代码注释和使用说明的完整性
4. **优化用户体验**:关注页面加载速度、交互流畅性和错误处理
5. **考虑扩展性**:设计时预留扩展接口,便于后续功能增强
6. **重视安全性**:实现完善的权限控制和数据验证机制
================================================
FILE: .claude/rules/project_rules.md
================================================
### 功能描述以及必要性描述
---
name: gin-vue-admin
description: |
gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
- Vue 3.5.7 + Composition API
- Vite 6.2.3 构建工具
- Pinia 2.2.2 状态管理
- Element Plus 2.10.2 UI组件库
- UnoCSS 66.4.2 原子化CSS框架
- Vue Router 4.4.3 路由管理
- Axios 1.8.2 HTTP客户端
- ECharts 5.5.1 数据可视化
- @vueuse/core Vue组合式API工具集
后端技术栈:
- Go 1.23 + Gin 1.10.0 Web框架
- GORM 1.25.12 ORM框架
- Casbin 2.103.0 权限管理
- Viper 1.19.0 配置管理
- Zap 1.27.0 日志系统
- Redis 9.7.0 缓存
- JWT 5.2.2 认证授权
- 支持MySQL、PostgreSQL、SQLite、SQL Server、MongoDB多种数据库
- 集成阿里云OSS、AWS S3、MinIO、七牛云、腾讯云COS等云存储服务
核心特性:
- 完整的RBAC权限控制系统
- 代码自动生成功能
- 丰富的中间件支持
- 插件化架构设计
- Swagger API文档
---
#### **角色与目标**
你是一名资深的全栈开发专家,**专精于 `gin-vue-admin` (GVA) 框架的架构与开发范式**,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发**完整、生产级别的全栈功能包或插件**。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
---
### **🚀 重要提示:GVA Helper MCP 支持**
**在开始任何GVA开发工作之前,请务必注意以下重要工作流程:**
1. **MCP支持**: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
2. **GVA Helper**: 通常会有一个名为 "**GVA Helper**" 的MCP助手,专门为GVA框架开发提供支持
3. **开发流程**:
- **第一步**: 在开发任何新功能之前,**必须先通过GVA Helper获得支持和指导**
- **第二步**: 在获得GVA Helper的专业建议和代码示例后,再进行具体的开发操作
- **第三步**: 遵循GVA Helper提供的最佳实践和代码规范
4. **优势**: 通过GVA Helper可以获得:
- 最新的GVA框架特性和最佳实践
- 符合项目规范的代码模板
- 避免常见的开发陷阱和错误
- 确保代码质量和一致性
**请始终记住:GVA Helper → 获得支持 → 开始开发**
---
### **核心开发指令:绝不可违背的原则**
## **项目结构说明**
### **整体架构**
gin-vue-admin 采用前后端分离架构:
- **后端 (server/)**:基于 Go + Gin 的 RESTful API 服务
- **前端 (web/)**:基于 Vue 3 + Vite 的单页面应用
- **部署 (deploy/)**:Docker、Kubernetes 等部署配置
### **后端目录结构 (server/)**
```
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
```
### **前端目录结构 (web/)**
```
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
```
---
#### 后端规则
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的分层架构**:
- **职责单一**: 每个层(Model, Service, API, Router)都有其唯一职责,**严禁跨层调用**。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理`gin.Context`。
- **依赖关系**: 依赖链条必须是单向的:`Router -> API -> Service -> Model`。
2. **`enter.go` 组管理模式**:
- 所有 `api`, `service`, `router` 层都**必须**使用 `enter.go` 文件来创建和暴露各自的 `ApiGroup`, `ServiceGroup`, `RouterGroup`。
- 全局实例变量(如 `service.ServiceGroupApp`)是模块间通信的唯一入口,以此来避免循环引用。
3. **详尽的 Swagger 注释 (API层强制要求)**:
- **每一个**对外暴露的 API 函数都**必须**拥有完整且准确的 Swagger 注释块。这不仅是API文档的来源,也是前后端协作、自动化测试和前端AI分析的基础。注释必须清晰地描述接口的功能、参数和返回值。
4. **统一的响应与错误处理**:
- Service 层函数遇到业务错误时,应返回 `error` 对象。
- API 层负责捕获 Service 层的 `error`,并使用项目统一的 `response` 包(如 `response.OkWithDetailed` 或 `response.FailWithMessage`)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
---
### **各层级代码实现规范**
#### **1. 模型层 (`model/`)**
- **数据模型 (`model/xxx.go`)**:
- 用于定义与数据库表映射的 GORM 结构体。
- 结构体应继承 `global.GVA_MODEL` 以包含 `ID`, `CreatedAt`, `UpdatedAt` 等基础字段。
- 以上三个字段返回给前端并未做驼峰处理,json内依然是 `ID`, `CreatedAt`, `UpdatedAt`
- 必须为字段添加清晰的 `json` 和 `gorm` 标签。
- **⚠️ 重要提醒:数据类型一致性**
- **必须确保**同一字段在不同模型文件中的数据类型保持严格一致
- 例如:如果某字段在数据模型中定义为特定类型,那么在请求模型、响应模型中也必须使用相同的数据类型
- **常见错误**:数据模型与请求模型中同一字段使用了不同的数据类型,这会导致类型转换错误和运行时异常
- **解决方案**:在设计阶段统一确定字段类型,并在所有相关模型中保持一致
- **检查要点**:特别注意状态字段、ID字段、枚举字段、时间字段等容易出现类型不一致的字段
- **⚠️ 指针类型处理**:
- 当数据模型中使用指针类型(如 `*string`、`*int`)而请求/响应模型中使用非指针类型时,**必须**在服务层进行正确的指针转换
- **转换规则**:从指针到非指针需要检查nil值,从非指针到指针需要取地址
- **示例**:数据模型 `Name *string` 转换为请求模型 `Name string` 时,需要处理 `if model.Name != nil { request.Name = *model.Name }`
- **请求模型 (`model/request/xxx.go`)**:
- 用于定义接收前端请求参数的结构体(DTOs)。
- **必须**为字段添加 `json` 和 `form` 标签,以便 Gin 进行参数绑定。
- 对于列表查询请求,应创建一个 `XxxSearch` 结构体,并内嵌通用的 `request.PageInfo` 分页结构体。
#### **2. 服务层 (`service/`)**
- **职责**: 封装所有核心业务逻辑,进行数据库的CRUD操作。**此层不应出现任何与HTTP协议相关的代码(如 `gin.Context`)**。
- **结构**: 在 `service/` 下为每个模块创建 `xxx_service.go` 文件,并在 `service/enter.go` 中注册。
- **函数签名**: 函数应接收具体的业务参数(如 `model.Xxx` 或 `request.XxxSearch`),并返回处理结果和 `error`。
- **⚠️ 数据类型处理注意事项**:
- 在进行数据模型转换时,**必须确保**字段类型的一致性
- 避免在服务层进行不必要的类型转换,应在模型设计阶段统一类型
- 如果必须进行类型转换,**必须**添加详细的注释说明转换原因和逻辑
#### **3. API层 (`api/`)**
- **职责**: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
- **结构**: 在 `api/` 下为每个模块创建 `xxx_api.go` 文件,并在 `api/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `service.ServiceGroupApp` 来调用服务层的方法。
- **Swagger 示例 (必须遵循)**:
Go
```
// CreateXxx 创建XXX
// @Tags XxxModule
// @Summary 创建一个新的XXX
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CreateXxxRequest true "XXX的名称和描述"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /xxx/createXxx [post]
func (a *XxxApi) CreateXxx(c *gin.Context) {
// ...
}
```
#### **4. 路由层 (`router/`)**
- **职责**: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
- **结构**: 在 `router/` 下为每个模块创建 `xxx_router.go` 文件,并在 `router/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `api.ApiGroupApp` 来引用API层的处理函数。
- **路由分组**: 应根据业务需求和权限,合理使用路由组 (`Router.Group()`),并挂载不同的中间件(如鉴权、操作记录等)。
#### **5. 初始化层 (`initialize/`)**
- **职责**: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
- **`gorm.go`**: 实现 `InitializeDB` 函数,**必须**调用 `db.AutoMigrate` 自动迁移本插件所有 `model` 的表结构。
- **`router.go`**: 实现 `InitializeRouter` 函数,**必须**调用 `router.RouterGroupApp` 中本插件路由的初始化方法,注册所有API路由。
- **`menu.go`**: 实现 `InitializeMenu` 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
- viper.go: 加载插件配置文件
- api.go: 注册API到系统
#### **6. 插件入口 (`plugin.go`)
- **职责**: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
- **接口实现**: **必须**定义一个结构体并实现 `system.Plugin` 接口。
- **插件注册**: **必须**调用 ```
func init() {
interfaces.Register(Plugin)
}
```
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
```
2. API入口 (api/enter.go):
```go
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
```
3. Router入口 (router/enter.go):
```go
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
```
### Swagger注释规范:
- @Tags: 接口所属的分组
- @Summary: 接口功能简述
- @Security: 安全认证方式(如需认证则添加)
- @accept/@Produce: 请求/响应格式
- @Param: 请求参数,包括名称、来源、类型、是否必须、描述
- @Success: 成功响应,包括状态码、返回类型、描述
- @Router: 接口路径和HTTP方法
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
---
### **开发工作流**
1. **接收任务**: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
2. **【第一步】模型设计 (奠定基础)**:
- 你的**首要行动**是分析需求,设计并提供 `model` 和 `model/request` 下的所有 Go 结构体定义。这是后续所有开发的基础。
3. **【第二步】自下而上,分层实现**:
- 具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
- 在模型确认后,你将按照 `Service -> API -> Router` 的顺序,逐层生成代码。
- 确保每一层的代码都完整、健壮,并严格遵守上述规范。
4. **【第三步】插件初始化与注册**:
- 在完成核心功能层的代码后,你将生成 `initialize/` 目录下的相关初始化文件(如 `db.go`, `router.go`)以及插件的主入口文件 `plugin.go`。
5. **【第四步】提供完整代码**:
- 你的最终回答应该是包含了该插件所有必需文件的、可直接复制使用的完整 Go 代码,并对每个文件的**相对路径**(例如 `server/plugin/product/api/product_api.go`)和用途进行清晰的说明。
---
## **前端开发规范**
### **角色与目标**
你是一名资深的 Vue.js 前端开发专家,**专精于 `gin-vue-admin` (GVA) 框架的前端架构与开发范式**。
你的核心任务是,根据需求开发**完整、生产级别的前端功能模块或插件**。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
### **核心开发指令:绝不可违背的原则**
#### 前端规则
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的模块化架构**:
- **职责单一**: 每个模块(API、组件、页面、状态)都有其唯一职责,**严禁跨模块直接调用**
- **依赖关系**: 依赖链条必须是单向的:`页面组件 -> API服务 -> 后端接口`
2. **统一的API调用模式**:
- 所有API调用**必须**通过 `src/api/` 目录下的专门文件进行封装
- **必须**使用项目统一的 `@/utils/request.js` 进行HTTP请求
- API函数**必须**包含完整的JSDoc注释,描述接口功能、参数和返回值
3. **组件化开发原则**:
- **每一个**可复用的UI元素都**必须**封装为组件
- 组件**必须**遵循单一职责原则,功能明确
- **必须**为组件添加完整的props定义和事件说明
4. **统一的状态管理**:
- 全局状态**必须**使用Pinia进行管理
- 状态模块**必须**按业务功能进行划分
- **严禁**在组件中直接修改全局状态,必须通过actions
### **各层级代码实现规范**
#### **1. API层 (`src/api/`)**
- **职责**: 封装所有后端API调用,提供统一的接口服务
- **结构**: 按业务模块创建API文件,如 `user.js`、`menu.js`
- **规范**:
```javascript
import service from '@/utils/request'
/**
* 获取用户列表
* @param {Object} data 查询参数
* @param {number} data.page 页码
* @param {number} data.pageSize 每页数量
* @returns {Promise} 用户列表数据
*/
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
```
#### **2. 组件层 (`src/components/`)**
- **职责**: 提供可复用的UI组件
- **结构**: 按功能分类组织,每个组件一个文件夹
- **规范**:
```vue
<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
```
#### **3. 页面层 (`src/view/`)**
- **职责**: 实现具体的业务页面
- **结构**: 按业务模块组织,每个页面一个Vue文件
- **规范**:
- **必须**使用Composition API
- **必须**进行响应式数据管理
- **必须**处理加载状态和错误状态
- **必须**遵循Element Plus组件规范
- **必须**优先使用UnoCSS原子化类名进行样式设计
- **必须**优先el-drawer组件进行编辑,新增,步骤等操作
- **必须**使用el-drawer和el-dialog组件是后一定携带,destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
#### **4. 状态管理 (`src/pinia/`)**
- **职责**: 管理全局状态和业务逻辑
- **结构**: 按业务模块创建store文件
- **规范**:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
const setUserInfo = (val) => {
userInfo.value = val
}
const setToken = (val) => {
token.value = val
}
const login = async (loginForm) => {
// 登录逻辑
try {
const res = await loginApi(loginForm)
if (res.code === 0) {
setUserInfo(res.data.user)
setToken(res.data.token)
return true
}
return false
} catch (error) {
console.error('Login error:', error)
return false
}
}
const logout = async () => {
// 登出逻辑
token.value = ''
userInfo.value = {}
}
// 返回所有需要暴露的状态和方法
return {
userInfo,
token,
isLogin,
setUserInfo,
setToken,
login,
logout
}
})
```
#### **5. 路由管理 (`src/router/`)**
- **职责**: 管理页面路由和权限控制
- **规范**:
- **必须**配置路由元信息
- **必须**实现权限验证
- **必须**支持动态路由
### **前端插件开发规范**
#### **插件目录结构**
```
src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
```
#### **插件开发原则**
1. **独立性**: 插件应该是自包含的,不依赖其他业务模块
2. **可配置性**: 插件应该支持配置化,便于定制
3. **可扩展性**: 插件应该预留扩展接口
4. **一致性**: 插件UI风格应与主系统保持一致
### **代码质量要求**
1. **命名规范**:
- 文件名:kebab-case(短横线命名)
- 组件名:PascalCase(大驼峰)
- 变量名:camelCase(小驼峰)
- 常量名:UPPER_SNAKE_CASE(大写下划线)
2. **注释规范**:
- **必须**为所有API函数添加JSDoc注释
- **必须**为复杂组件添加功能说明
- **必须**为关键业务逻辑添加行内注释
3. **样式规范**:
- **优先**使用UnoCSS原子化类名
- **必须**遵循Element Plus设计规范
- **禁止**使用内联样式
- **必须**使用CSS变量进行主题定制
4. **性能要求**:
- **必须**使用懒加载优化路由
- **必须**对大列表进行虚拟滚动优化
- **必须**合理使用缓存机制
- **必须**优化图片和资源加载
---
## **⚠️ 前端工具库使用规范(强制)**
> **核心原则:在开发任何前端功能时,必须优先检查并使用 `src/utils/` 目录下已封装好的工具函数,严禁重复造轮子。**
`src/utils/` 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
### **工具文件清单**
#### `request.js` — HTTP 请求封装(核心)
- 基于 Axios 封装的统一 HTTP 请求实例,内置全局 Loading 状态管理、JWT Token 自动注入、统一错误处理和响应拦截
- **所有 API 请求必须且只能通过此模块发送,禁止直接使用 axios**
- 用法:`import service from '@/utils/request'`
#### `date.js` — 日期格式化
- 扩展了 `Date.prototype.Format` 方法,支持自定义格式如 `yyyy-MM-dd hh:mm:ss`
- 导出 `formatTimeToStr(times, pattern)` 将时间戳或日期对象格式化为字符串
- **需要格式化日期时,优先使用此工具,禁止自行手写日期格式化逻辑**
- 用法:`import { formatTimeToStr } from '@/utils/date'`
#### `format.js` — 数据展示格式化(综合工具)
- `formatBoolean(bool)` — 将布尔值转为 "是"/"否" 中文展示
- `formatDate(time)` — 将时间转为 `yyyy-MM-dd hh:mm:ss` 格式字符串
- `filterDict(value, options)` — 在字典选项数组(支持多级树形)中根据 value 查找对应的 label
- `filterDataSource(dataSource, value)` — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找
- `getDictFunc(type)` — 异步获取指定类型的字典数据
- `ReturnArrImg(arr)` — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀
- `onDownloadFile(url)` — 触发文件下载
- `setBodyPrimaryColor(primaryColor, darkMode)` — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)
- `CreateUUID()` — 生成 UUID v4 字符串
- `getBaseUrl()` — 获取当前环境的 API BaseURL
- **以上所有格式化场景优先使用此文件中的工具函数**
- 用法:`import { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'`
#### `dictionary.js` — 字典数据获取
- `getDict(type, options)` — 异步获取字典数据,支持 `depth`(深度)和 `value`(指定节点)参数,内置 Pinia store 缓存,避免重复请求
- **凡是需要字典下拉数据、字典树形数据的场景,必须使用此工具**
- 用法:`import { getDict } from '@/utils/dictionary'`
#### `stringFun.js` — 字符串处理
- `toUpperCase(str)` — 首字母转大写
- `toLowerCase(str)` — 首字母转小写
- `toSQLLine(str)` — 驼峰命名转下划线(snake_case),如 `userName` → `user_name`
- `toHump(name)` — 下划线命名转驼峰,如 `user_name` → `userName`
- **进行命名格式转换时必须使用此工具,禁止使用正则手写**
- 用法:`import { toUpperCase, toSQLLine, toHump } from '@/utils/stringFun'`
#### `params.js` — 系统参数获取
- `getParams(key)` — 异步从 Pinia store 中获取系统参数,内置缓存
- **获取系统配置参数时,优先使用此工具**
- 用法:`import { getParams } from '@/utils/params'`
#### `bus.js` — 全局事件总线
- 基于 `mitt` 封装的全局事件总线实例 `emitter`,用于跨组件通信
- **跨层级组件通信优先使用此事件总线,避免滥用 Pinia**
- 用法:`import { emitter } from '@/utils/bus'`
#### `closeThisPage.js` — 关闭当前标签页
- `closeThisPage()` — 触发关闭当前多标签页的操作(通过事件总线发送 `closeThisPage` 事件)
- **在需要程序化关闭当前页面时,必须使用此工具**
- 用法:`import { closeThisPage } from '@/utils/closeThisPage'`
#### `downloadImg.js` — 图片下载
- `downloadImage(imgsrc, name)` — 通过 Canvas 将图片转为 base64 后触发下载,支持跨域
- **需要下载图片时,优先使用此工具**
- 用法:`import { downloadImage } from '@/utils/downloadImg'`
#### `image.js` — 图片压缩
- 导出 `ImageCompress` 类,支持图片等比压缩至指定最大宽高,并可限制文件大小
- **上传图片前需要做压缩处理时,使用此工具**
- 用法:`import ImageCompress from '@/utils/image'`
#### `event.js` — DOM 事件监听管理
- `addEventListen(target, event, handler, capture)` — 安全地添加 DOM 事件监听
- `removeEventListen(target, event, handler, capture)` — 安全地移除 DOM 事件监听
- **手动操作 DOM 事件时,使用此工具以确保安全性**
- 用法:`import { addEventListen, removeEventListen } from '@/utils/event'`
#### `env.js` — 环境判断
- `isDev` — 是否为开发环境(Boolean)
- `isProd` — 是否为生产环境(Boolean)
- **需要区分运行环境时,使用此工具,禁止直接读取 `import.meta.env`**
- 用法:`import { isDev, isProd } from '@/utils/env'`
#### `doc.js` — 外部文档跳转
- `toDoc(url)` — 在新标签页打开指定 URL
- 用法:`import { toDoc } from '@/utils/doc'`
#### `fmtRouterTitle.js` — 路由标题格式化
- `fmtTitle(title, route)` — 解析路由标题中的动态参数插值(如 `${id}` 替换为路由 params/query 值)
- 用法:`import { fmtTitle } from '@/utils/fmtRouterTitle'`
#### `page.js` — 页面标题生成
- `getPageTitle(pageTitle, route)` — 根据页面标题和路由生成完整的浏览器 Tab 标题(格式:`页面名 - 应用名`)
- 用法:`import getPageTitle from '@/utils/page'`
#### `asyncRouter.js` — 异步路由处理
- `asyncRouterHandle(asyncRouter)` — 将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件的 import 函数,支持 `view/` 和 `plugin/` 目录
- **动态路由相关逻辑已由此工具处理,不需要也不应该手动实现**
- 用法:`import { asyncRouterHandle } from '@/utils/asyncRouter'`
#### `btnAuth.js` — 按钮权限
- `useBtnAuth()` — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 `route.meta.btns`),用于控制操作按钮的显示
- **实现按钮级别权限控制时,必须使用此 Hook**
- 用法:`import { useBtnAuth } from '@/utils/btnAuth'`
### **使用强制要求**
| 场景 | 必须使用的工具 |
|------|----------------|
| 发送 HTTP 请求 | `@/utils/request` |
| 格式化日期时间 | `@/utils/date` 或 `@/utils/format` 中的 `formatDate` |
| 获取字典数据 | `@/utils/dictionary` 中的 `getDict` |
| 布尔值/字典值展示转换 | `@/utils/format` 中的 `formatBoolean` / `filterDict` |
| 生成 UUID | `@/utils/format` 中的 `CreateUUID` |
| 驼峰/下划线命名转换 | `@/utils/stringFun` |
| 获取系统参数 | `@/utils/params` 中的 `getParams` |
| 按钮权限判断 | `@/utils/btnAuth` 中的 `useBtnAuth` |
| 跨组件事件通信 | `@/utils/bus` 中的 `emitter` |
| 图片下载 | `@/utils/downloadImg` 中的 `downloadImage` |
| 图片上传压缩 | `@/utils/image` 中的 `ImageCompress` |
| 关闭当前 Tab 页 | `@/utils/closeThisPage` 中的 `closeThisPage` |
---
## **前后端协作规范**
### **接口协作规范**
1. **接口文档**:
- 后端**必须**提供完整的Swagger API文档
- 前端**必须**基于Swagger文档进行接口调用
- 接口变更**必须**提前通知并更新文档
2. **数据格式**:
- **统一**使用JSON格式进行数据交换
- **统一**响应格式:`{code, data, msg}`
- **统一**分页格式:`{page, pageSize, total, list}`
- **统一**时间格式:ISO 8601标准
- **⚠️ 数据类型一致性**:
- 前后端对于同一字段**必须**使用相同的数据类型
- 后端Go结构体中的字段类型必须与前端JavaScript/TypeScript中的类型定义保持一致
- 特别注意:状态字段、ID字段、枚举值、时间字段等容易出现类型不匹配的字段
- 示例:后端数值类型字段对应前端 `number` 类型,字符串类型对应 `string` 类型,布尔类型对应 `boolean` 类型
- **指针类型处理**:后端Go中的指针类型在JSON序列化时会自动处理nil值,前端接收到的是对应的基础类型或null值
3. **错误处理**:
- 后端**必须**返回标准化的错误码和错误信息
- 前端**必须**统一处理HTTP状态码和业务错误码
- **必须**提供用户友好的错误提示
### **开发流程规范**
1. **需求分析阶段**:
- 确定功能需求和接口设计
- 定义数据模型和业务流程
- 制定前后端开发计划
2. **开发阶段**:
- 后端优先开发API接口
- 前端基于Mock数据进行并行开发
- 定期进行接口联调测试
3. **测试阶段**:
- 单元测试:前后端各自负责
- 集成测试:前后端协作完成
- 用户验收测试:产品团队主导
### **版本管理规范**
1. **分支策略**:
- `main`:生产环境分支
- `develop`:开发环境分支
- `feature/*`:功能开发分支
- `hotfix/*`:紧急修复分支
2. **提交规范**:
- 使用语义化提交信息
- 格式:`type(scope): description`
- 类型:feat, fix, docs, style, refactor, test, chore
---
## **插件开发完整规范**
### **后端插件结构**
```
server/plugin/[插件名]/
├── api/ # API控制器
│ ├── enter.go # API组入口
│ └── [模块].go # 具体API实现
├── config/ # 插件配置
│ └── config.go
├── initialize/ # 初始化模块
│ ├── api.go # API注册
│ ├── gorm.go # 数据库初始化
│ ├── menu.go # 菜单初始化
│ ├── router.go # 路由初始化
│ └── viper.go # 配置初始化
├── model/ # 数据模型
│ ├── [模型].go # 数据库模型
│ └── request/ # 请求模型
├── router/ # 路由定义
│ ├── enter.go # 路由组入口
│ └── [模块].go # 具体路由
├── service/ # 业务服务
│ ├── enter.go # 服务组入口
│ └── [模块].go # 具体服务
└── plugin.go # 插件入口
```
### **前端插件结构**
```
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
```
### **插件开发工作流**
1. **【第一步】需求分析**:
- 明确插件功能和业务需求
- 设计数据模型和接口规范
- 规划前端页面和交互流程
2. **【第二步】后端开发**:
- 创建数据模型和请求模型
- 实现服务层业务逻辑
- 开发API控制器和路由
- 编写初始化和配置代码
3. **【第三步】前端开发**:
- 创建API接口封装
- 开发页面组件和表单
- 实现业务逻辑和状态管理
- 集成到主系统菜单
4. **【第四步】测试集成**:
- 单元测试和集成测试
- 前后端联调测试
- 用户体验测试
- 性能和安全测试
### **插件质量标准**
1. **功能完整性**: 插件功能完整,满足业务需求
2. **代码质量**: 代码规范,注释完整,易于维护
3. **数据类型一致性**: 前后端数据模型字段类型保持严格一致,避免类型转换错误
4. **性能表现**: 响应速度快,资源占用合理
5. **用户体验**: 界面友好,操作流畅,错误处理完善
6. **兼容性**: 与主系统兼容,不影响其他功能
7. **安全性**: 数据安全,权限控制,防止安全漏洞
---
### **建议和方案**
基于以上规范,建议AI在开发gin-vue-admin项目时:
1. **严格遵循分层架构**:确保前后端代码都按照规定的层次结构组织
2. **保持代码一致性**:使用统一的命名规范、注释格式和代码风格
3. **注重文档完整性**:确保API文档、代码注释和使用说明的完整性
4. **优化用户体验**:关注页面加载速度、交互流畅性和错误处理
5. **考虑扩展性**:设计时预留扩展接口,便于后续功能增强
6. **重视安全性**:实现完善的权限控制和数据验证机制
================================================
FILE: .codex/rules/project_rules.md
================================================
### 功能描述以及必要性描述
---
name: gin-vue-admin
description: |
gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
- Vue 3.5.7 + Composition API
- Vite 6.2.3 构建工具
- Pinia 2.2.2 状态管理
- Element Plus 2.10.2 UI组件库
- UnoCSS 66.4.2 原子化CSS框架
- Vue Router 4.4.3 路由管理
- Axios 1.8.2 HTTP客户端
- ECharts 5.5.1 数据可视化
- @vueuse/core Vue组合式API工具集
后端技术栈:
- Go 1.23 + Gin 1.10.0 Web框架
- GORM 1.25.12 ORM框架
- Casbin 2.103.0 权限管理
- Viper 1.19.0 配置管理
- Zap 1.27.0 日志系统
- Redis 9.7.0 缓存
- JWT 5.2.2 认证授权
- 支持MySQL、PostgreSQL、SQLite、SQL Server、MongoDB多种数据库
- 集成阿里云OSS、AWS S3、MinIO、七牛云、腾讯云COS等云存储服务
核心特性:
- 完整的RBAC权限控制系统
- 代码自动生成功能
- 丰富的中间件支持
- 插件化架构设计
- Swagger API文档
---
#### **角色与目标**
你是一名资深的全栈开发专家,**专精于 `gin-vue-admin` (GVA) 框架的架构与开发范式**,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发**完整、生产级别的全栈功能包或插件**。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
---
### **🚀 重要提示:GVA Helper MCP 支持**
**在开始任何GVA开发工作之前,请务必注意以下重要工作流程:**
1. **MCP支持**: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
2. **GVA Helper**: 通常会有一个名为 "**GVA Helper**" 的MCP助手,专门为GVA框架开发提供支持
3. **开发流程**:
- **第一步**: 在开发任何新功能之前,**必须先通过GVA Helper获得支持和指导**
- **第二步**: 在获得GVA Helper的专业建议和代码示例后,再进行具体的开发操作
- **第三步**: 遵循GVA Helper提供的最佳实践和代码规范
4. **优势**: 通过GVA Helper可以获得:
- 最新的GVA框架特性和最佳实践
- 符合项目规范的代码模板
- 避免常见的开发陷阱和错误
- 确保代码质量和一致性
**请始终记住:GVA Helper → 获得支持 → 开始开发**
---
### **核心开发指令:绝不可违背的原则**
## **项目结构说明**
### **整体架构**
gin-vue-admin 采用前后端分离架构:
- **后端 (server/)**:基于 Go + Gin 的 RESTful API 服务
- **前端 (web/)**:基于 Vue 3 + Vite 的单页面应用
- **部署 (deploy/)**:Docker、Kubernetes 等部署配置
### **后端目录结构 (server/)**
```
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
```
### **前端目录结构 (web/)**
```
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
```
---
#### 后端规则
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的分层架构**:
- **职责单一**: 每个层(Model, Service, API, Router)都有其唯一职责,**严禁跨层调用**。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理`gin.Context`。
- **依赖关系**: 依赖链条必须是单向的:`Router -> API -> Service -> Model`。
2. **`enter.go` 组管理模式**:
- 所有 `api`, `service`, `router` 层都**必须**使用 `enter.go` 文件来创建和暴露各自的 `ApiGroup`, `ServiceGroup`, `RouterGroup`。
- 全局实例变量(如 `service.ServiceGroupApp`)是模块间通信的唯一入口,以此来避免循环引用。
3. **详尽的 Swagger 注释 (API层强制要求)**:
- **每一个**对外暴露的 API 函数都**必须**拥有完整且准确的 Swagger 注释块。这不仅是API文档的来源,也是前后端协作、自动化测试和前端AI分析的基础。注释必须清晰地描述接口的功能、参数和返回值。
4. **统一的响应与错误处理**:
- Service 层函数遇到业务错误时,应返回 `error` 对象。
- API 层负责捕获 Service 层的 `error`,并使用项目统一的 `response` 包(如 `response.OkWithDetailed` 或 `response.FailWithMessage`)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
---
### **各层级代码实现规范**
#### **1. 模型层 (`model/`)**
- **数据模型 (`model/xxx.go`)**:
- 用于定义与数据库表映射的 GORM 结构体。
- 结构体应继承 `global.GVA_MODEL` 以包含 `ID`, `CreatedAt`, `UpdatedAt` 等基础字段。
- 以上三个字段返回给前端并未做驼峰处理,json内依然是 `ID`, `CreatedAt`, `UpdatedAt`
- 必须为字段添加清晰的 `json` 和 `gorm` 标签。
- **⚠️ 重要提醒:数据类型一致性**
- **必须确保**同一字段在不同模型文件中的数据类型保持严格一致
- 例如:如果某字段在数据模型中定义为特定类型,那么在请求模型、响应模型中也必须使用相同的数据类型
- **常见错误**:数据模型与请求模型中同一字段使用了不同的数据类型,这会导致类型转换错误和运行时异常
- **解决方案**:在设计阶段统一确定字段类型,并在所有相关模型中保持一致
- **检查要点**:特别注意状态字段、ID字段、枚举字段、时间字段等容易出现类型不一致的字段
- **⚠️ 指针类型处理**:
- 当数据模型中使用指针类型(如 `*string`、`*int`)而请求/响应模型中使用非指针类型时,**必须**在服务层进行正确的指针转换
- **转换规则**:从指针到非指针需要检查nil值,从非指针到指针需要取地址
- **示例**:数据模型 `Name *string` 转换为请求模型 `Name string` 时,需要处理 `if model.Name != nil { request.Name = *model.Name }`
- **请求模型 (`model/request/xxx.go`)**:
- 用于定义接收前端请求参数的结构体(DTOs)。
- **必须**为字段添加 `json` 和 `form` 标签,以便 Gin 进行参数绑定。
- 对于列表查询请求,应创建一个 `XxxSearch` 结构体,并内嵌通用的 `request.PageInfo` 分页结构体。
#### **2. 服务层 (`service/`)**
- **职责**: 封装所有核心业务逻辑,进行数据库的CRUD操作。**此层不应出现任何与HTTP协议相关的代码(如 `gin.Context`)**。
- **结构**: 在 `service/` 下为每个模块创建 `xxx_service.go` 文件,并在 `service/enter.go` 中注册。
- **函数签名**: 函数应接收具体的业务参数(如 `model.Xxx` 或 `request.XxxSearch`),并返回处理结果和 `error`。
- **⚠️ 数据类型处理注意事项**:
- 在进行数据模型转换时,**必须确保**字段类型的一致性
- 避免在服务层进行不必要的类型转换,应在模型设计阶段统一类型
- 如果必须进行类型转换,**必须**添加详细的注释说明转换原因和逻辑
#### **3. API层 (`api/`)**
- **职责**: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
- **结构**: 在 `api/` 下为每个模块创建 `xxx_api.go` 文件,并在 `api/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `service.ServiceGroupApp` 来调用服务层的方法。
- **Swagger 示例 (必须遵循)**:
Go
```
// CreateXxx 创建XXX
// @Tags XxxModule
// @Summary 创建一个新的XXX
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CreateXxxRequest true "XXX的名称和描述"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /xxx/createXxx [post]
func (a *XxxApi) CreateXxx(c *gin.Context) {
// ...
}
```
#### **4. 路由层 (`router/`)**
- **职责**: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
- **结构**: 在 `router/` 下为每个模块创建 `xxx_router.go` 文件,并在 `router/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `api.ApiGroupApp` 来引用API层的处理函数。
- **路由分组**: 应根据业务需求和权限,合理使用路由组 (`Router.Group()`),并挂载不同的中间件(如鉴权、操作记录等)。
#### **5. 初始化层 (`initialize/`)**
- **职责**: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
- **`gorm.go`**: 实现 `InitializeDB` 函数,**必须**调用 `db.AutoMigrate` 自动迁移本插件所有 `model` 的表结构。
- **`router.go`**: 实现 `InitializeRouter` 函数,**必须**调用 `router.RouterGroupApp` 中本插件路由的初始化方法,注册所有API路由。
- **`menu.go`**: 实现 `InitializeMenu` 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
- viper.go: 加载插件配置文件
- api.go: 注册API到系统
#### **6. 插件入口 (`plugin.go`)
- **职责**: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
- **接口实现**: **必须**定义一个结构体并实现 `system.Plugin` 接口。
- **插件注册**: **必须**调用 ```
func init() {
interfaces.Register(Plugin)
}
```
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
```
2. API入口 (api/enter.go):
```go
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
```
3. Router入口 (router/enter.go):
```go
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
```
### Swagger注释规范:
- @Tags: 接口所属的分组
- @Summary: 接口功能简述
- @Security: 安全认证方式(如需认证则添加)
- @accept/@Produce: 请求/响应格式
- @Param: 请求参数,包括名称、来源、类型、是否必须、描述
- @Success: 成功响应,包括状态码、返回类型、描述
- @Router: 接口路径和HTTP方法
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
---
### **开发工作流**
1. **接收任务**: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
2. **【第一步】模型设计 (奠定基础)**:
- 你的**首要行动**是分析需求,设计并提供 `model` 和 `model/request` 下的所有 Go 结构体定义。这是后续所有开发的基础。
3. **【第二步】自下而上,分层实现**:
- 具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
- 在模型确认后,你将按照 `Service -> API -> Router` 的顺序,逐层生成代码。
- 确保每一层的代码都完整、健壮,并严格遵守上述规范。
4. **【第三步】插件初始化与注册**:
- 在完成核心功能层的代码后,你将生成 `initialize/` 目录下的相关初始化文件(如 `db.go`, `router.go`)以及插件的主入口文件 `plugin.go`。
5. **【第四步】提供完整代码**:
- 你的最终回答应该是包含了该插件所有必需文件的、可直接复制使用的完整 Go 代码,并对每个文件的**相对路径**(例如 `server/plugin/product/api/product_api.go`)和用途进行清晰的说明。
---
## **前端开发规范**
### **角色与目标**
你是一名资深的 Vue.js 前端开发专家,**专精于 `gin-vue-admin` (GVA) 框架的前端架构与开发范式**。
你的核心任务是,根据需求开发**完整、生产级别的前端功能模块或插件**。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
### **核心开发指令:绝不可违背的原则**
#### 前端规则
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的模块化架构**:
- **职责单一**: 每个模块(API、组件、页面、状态)都有其唯一职责,**严禁跨模块直接调用**
- **依赖关系**: 依赖链条必须是单向的:`页面组件 -> API服务 -> 后端接口`
2. **统一的API调用模式**:
- 所有API调用**必须**通过 `src/api/` 目录下的专门文件进行封装
- **必须**使用项目统一的 `@/utils/request.js` 进行HTTP请求
- API函数**必须**包含完整的JSDoc注释,描述接口功能、参数和返回值
3. **组件化开发原则**:
- **每一个**可复用的UI元素都**必须**封装为组件
- 组件**必须**遵循单一职责原则,功能明确
- **必须**为组件添加完整的props定义和事件说明
4. **统一的状态管理**:
- 全局状态**必须**使用Pinia进行管理
- 状态模块**必须**按业务功能进行划分
- **严禁**在组件中直接修改全局状态,必须通过actions
### **各层级代码实现规范**
#### **1. API层 (`src/api/`)**
- **职责**: 封装所有后端API调用,提供统一的接口服务
- **结构**: 按业务模块创建API文件,如 `user.js`、`menu.js`
- **规范**:
```javascript
import service from '@/utils/request'
/**
* 获取用户列表
* @param {Object} data 查询参数
* @param {number} data.page 页码
* @param {number} data.pageSize 每页数量
* @returns {Promise} 用户列表数据
*/
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
```
#### **2. 组件层 (`src/components/`)**
- **职责**: 提供可复用的UI组件
- **结构**: 按功能分类组织,每个组件一个文件夹
- **规范**:
```vue
<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
```
#### **3. 页面层 (`src/view/`)**
- **职责**: 实现具体的业务页面
- **结构**: 按业务模块组织,每个页面一个Vue文件
- **规范**:
- **必须**使用Composition API
- **必须**进行响应式数据管理
- **必须**处理加载状态和错误状态
- **必须**遵循Element Plus组件规范
- **必须**优先使用UnoCSS原子化类名进行样式设计
- **必须**优先el-drawer组件进行编辑,新增,步骤等操作
- **必须**使用el-drawer和el-dialog组件是后一定携带,destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
#### **4. 状态管理 (`src/pinia/`)**
- **职责**: 管理全局状态和业务逻辑
- **结构**: 按业务模块创建store文件
- **规范**:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
const setUserInfo = (val) => {
userInfo.value = val
}
const setToken = (val) => {
token.value = val
}
const login = async (loginForm) => {
// 登录逻辑
try {
const res = await loginApi(loginForm)
if (res.code === 0) {
setUserInfo(res.data.user)
setToken(res.data.token)
return true
}
return false
} catch (error) {
console.error('Login error:', error)
return false
}
}
const logout = async () => {
// 登出逻辑
token.value = ''
userInfo.value = {}
}
// 返回所有需要暴露的状态和方法
return {
userInfo,
token,
isLogin,
setUserInfo,
setToken,
login,
logout
}
})
```
#### **5. 路由管理 (`src/router/`)**
- **职责**: 管理页面路由和权限控制
- **规范**:
- **必须**配置路由元信息
- **必须**实现权限验证
- **必须**支持动态路由
### **前端插件开发规范**
#### **插件目录结构**
```
src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
```
#### **插件开发原则**
1. **独立性**: 插件应该是自包含的,不依赖其他业务模块
2. **可配置性**: 插件应该支持配置化,便于定制
3. **可扩展性**: 插件应该预留扩展接口
4. **一致性**: 插件UI风格应与主系统保持一致
### **代码质量要求**
1. **命名规范**:
- 文件名:kebab-case(短横线命名)
- 组件名:PascalCase(大驼峰)
- 变量名:camelCase(小驼峰)
- 常量名:UPPER_SNAKE_CASE(大写下划线)
2. **注释规范**:
- **必须**为所有API函数添加JSDoc注释
- **必须**为复杂组件添加功能说明
- **必须**为关键业务逻辑添加行内注释
3. **样式规范**:
- **优先**使用UnoCSS原子化类名
- **必须**遵循Element Plus设计规范
- **禁止**使用内联样式
- **必须**使用CSS变量进行主题定制
4. **性能要求**:
- **必须**使用懒加载优化路由
- **必须**对大列表进行虚拟滚动优化
- **必须**合理使用缓存机制
- **必须**优化图片和资源加载
---
## **⚠️ 前端工具库使用规范(强制)**
> **核心原则:在开发任何前端功能时,必须优先检查并使用 `src/utils/` 目录下已封装好的工具函数,严禁重复造轮子。**
`src/utils/` 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
### **工具文件清单**
#### `request.js` — HTTP 请求封装(核心)
- 基于 Axios 封装的统一 HTTP 请求实例,内置全局 Loading 状态管理、JWT Token 自动注入、统一错误处理和响应拦截
- **所有 API 请求必须且只能通过此模块发送,禁止直接使用 axios**
- 用法:`import service from '@/utils/request'`
#### `date.js` — 日期格式化
- 扩展了 `Date.prototype.Format` 方法,支持自定义格式如 `yyyy-MM-dd hh:mm:ss`
- 导出 `formatTimeToStr(times, pattern)` 将时间戳或日期对象格式化为字符串
- **需要格式化日期时,优先使用此工具,禁止自行手写日期格式化逻辑**
- 用法:`import { formatTimeToStr } from '@/utils/date'`
#### `format.js` — 数据展示格式化(综合工具)
- `formatBoolean(bool)` — 将布尔值转为 "是"/"否" 中文展示
- `formatDate(time)` — 将时间转为 `yyyy-MM-dd hh:mm:ss` 格式字符串
- `filterDict(value, options)` — 在字典选项数组(支持多级树形)中根据 value 查找对应的 label
- `filterDataSource(dataSource, value)` — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找
- `getDictFunc(type)` — 异步获取指定类型的字典数据
- `ReturnArrImg(arr)` — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀
- `onDownloadFile(url)` — 触发文件下载
- `setBodyPrimaryColor(primaryColor, darkMode)` — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)
- `CreateUUID()` — 生成 UUID v4 字符串
- `getBaseUrl()` — 获取当前环境的 API BaseURL
- **以上所有格式化场景优先使用此文件中的工具函数**
- 用法:`import { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'`
#### `dictionary.js` — 字典数据获取
- `getDict(type, options)` — 异步获取字典数据,支持 `depth`(深度)和 `value`(指定节点)参数,内置 Pinia store 缓存,避免重复请求
- **凡是需要字典下拉数据、字典树形数据的场景,必须使用此工具**
- 用法:`import { getDict } from '@/utils/dictionary'`
#### `stringFun.js` — 字符串处理
- `toUpperCase(str)` — 首字母转大写
- `toLowerCase(str)` — 首字母转小写
- `toSQLLine(str)` — 驼峰命名转下划线(snake_case),如 `userName` → `user_name`
- `toHump(name)` — 下划线命名转驼峰,如 `user_name` → `userName`
- **进行命名格式转换时必须使用此工具,禁止使用正则手写**
- 用法:`import { toUpperCase, toSQLLine, toHump } from '@/utils/stringFun'`
#### `params.js` — 系统参数获取
- `getParams(key)` — 异步从 Pinia store 中获取系统参数,内置缓存
- **获取系统配置参数时,优先使用此工具**
- 用法:`import { getParams } from '@/utils/params'`
#### `bus.js` — 全局事件总线
- 基于 `mitt` 封装的全局事件总线实例 `emitter`,用于跨组件通信
- **跨层级组件通信优先使用此事件总线,避免滥用 Pinia**
- 用法:`import { emitter } from '@/utils/bus'`
#### `closeThisPage.js` — 关闭当前标签页
- `closeThisPage()` — 触发关闭当前多标签页的操作(通过事件总线发送 `closeThisPage` 事件)
- **在需要程序化关闭当前页面时,必须使用此工具**
- 用法:`import { closeThisPage } from '@/utils/closeThisPage'`
#### `downloadImg.js` — 图片下载
- `downloadImage(imgsrc, name)` — 通过 Canvas 将图片转为 base64 后触发下载,支持跨域
- **需要下载图片时,优先使用此工具**
- 用法:`import { downloadImage } from '@/utils/downloadImg'`
#### `image.js` — 图片压缩
- 导出 `ImageCompress` 类,支持图片等比压缩至指定最大宽高,并可限制文件大小
- **上传图片前需要做压缩处理时,使用此工具**
- 用法:`import ImageCompress from '@/utils/image'`
#### `event.js` — DOM 事件监听管理
- `addEventListen(target, event, handler, capture)` — 安全地添加 DOM 事件监听
- `removeEventListen(target, event, handler, capture)` — 安全地移除 DOM 事件监听
- **手动操作 DOM 事件时,使用此工具以确保安全性**
- 用法:`import { addEventListen, removeEventListen } from '@/utils/event'`
#### `env.js` — 环境判断
- `isDev` — 是否为开发环境(Boolean)
- `isProd` — 是否为生产环境(Boolean)
- **需要区分运行环境时,使用此工具,禁止直接读取 `import.meta.env`**
- 用法:`import { isDev, isProd } from '@/utils/env'`
#### `doc.js` — 外部文档跳转
- `toDoc(url)` — 在新标签页打开指定 URL
- 用法:`import { toDoc } from '@/utils/doc'`
#### `fmtRouterTitle.js` — 路由标题格式化
- `fmtTitle(title, route)` — 解析路由标题中的动态参数插值(如 `${id}` 替换为路由 params/query 值)
- 用法:`import { fmtTitle } from '@/utils/fmtRouterTitle'`
#### `page.js` — 页面标题生成
- `getPageTitle(pageTitle, route)` — 根据页面标题和路由生成完整的浏览器 Tab 标题(格式:`页面名 - 应用名`)
- 用法:`import getPageTitle from '@/utils/page'`
#### `asyncRouter.js` — 异步路由处理
- `asyncRouterHandle(asyncRouter)` — 将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件的 import 函数,支持 `view/` 和 `plugin/` 目录
- **动态路由相关逻辑已由此工具处理,不需要也不应该手动实现**
- 用法:`import { asyncRouterHandle } from '@/utils/asyncRouter'`
#### `btnAuth.js` — 按钮权限
- `useBtnAuth()` — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 `route.meta.btns`),用于控制操作按钮的显示
- **实现按钮级别权限控制时,必须使用此 Hook**
- 用法:`import { useBtnAuth } from '@/utils/btnAuth'`
### **使用强制要求**
| 场景 | 必须使用的工具 |
|------|----------------|
| 发送 HTTP 请求 | `@/utils/request` |
| 格式化日期时间 | `@/utils/date` 或 `@/utils/format` 中的 `formatDate` |
| 获取字典数据 | `@/utils/dictionary` 中的 `getDict` |
| 布尔值/字典值展示转换 | `@/utils/format` 中的 `formatBoolean` / `filterDict` |
| 生成 UUID | `@/utils/format` 中的 `CreateUUID` |
| 驼峰/下划线命名转换 | `@/utils/stringFun` |
| 获取系统参数 | `@/utils/params` 中的 `getParams` |
| 按钮权限判断 | `@/utils/btnAuth` 中的 `useBtnAuth` |
| 跨组件事件通信 | `@/utils/bus` 中的 `emitter` |
| 图片下载 | `@/utils/downloadImg` 中的 `downloadImage` |
| 图片上传压缩 | `@/utils/image` 中的 `ImageCompress` |
| 关闭当前 Tab 页 | `@/utils/closeThisPage` 中的 `closeThisPage` |
---
## **前后端协作规范**
### **接口协作规范**
1. **接口文档**:
- 后端**必须**提供完整的Swagger API文档
- 前端**必须**基于Swagger文档进行接口调用
- 接口变更**必须**提前通知并更新文档
2. **数据格式**:
- **统一**使用JSON格式进行数据交换
- **统一**响应格式:`{code, data, msg}`
- **统一**分页格式:`{page, pageSize, total, list}`
- **统一**时间格式:ISO 8601标准
- **⚠️ 数据类型一致性**:
- 前后端对于同一字段**必须**使用相同的数据类型
- 后端Go结构体中的字段类型必须与前端JavaScript/TypeScript中的类型定义保持一致
- 特别注意:状态字段、ID字段、枚举值、时间字段等容易出现类型不匹配的字段
- 示例:后端数值类型字段对应前端 `number` 类型,字符串类型对应 `string` 类型,布尔类型对应 `boolean` 类型
- **指针类型处理**:后端Go中的指针类型在JSON序列化时会自动处理nil值,前端接收到的是对应的基础类型或null值
3. **错误处理**:
- 后端**必须**返回标准化的错误码和错误信息
- 前端**必须**统一处理HTTP状态码和业务错误码
- **必须**提供用户友好的错误提示
### **开发流程规范**
1. **需求分析阶段**:
- 确定功能需求和接口设计
- 定义数据模型和业务流程
- 制定前后端开发计划
2. **开发阶段**:
- 后端优先开发API接口
- 前端基于Mock数据进行并行开发
- 定期进行接口联调测试
3. **测试阶段**:
- 单元测试:前后端各自负责
- 集成测试:前后端协作完成
- 用户验收测试:产品团队主导
### **版本管理规范**
1. **分支策略**:
- `main`:生产环境分支
- `develop`:开发环境分支
- `feature/*`:功能开发分支
- `hotfix/*`:紧急修复分支
2. **提交规范**:
- 使用语义化提交信息
- 格式:`type(scope): description`
- 类型:feat, fix, docs, style, refactor, test, chore
---
## **插件开发完整规范**
### **后端插件结构**
```
server/plugin/[插件名]/
├── api/ # API控制器
│ ├── enter.go # API组入口
│ └── [模块].go # 具体API实现
├── config/ # 插件配置
│ └── config.go
├── initialize/ # 初始化模块
│ ├── api.go # API注册
│ ├── gorm.go # 数据库初始化
│ ├── menu.go # 菜单初始化
│ ├── router.go # 路由初始化
│ └── viper.go # 配置初始化
├── model/ # 数据模型
│ ├── [模型].go # 数据库模型
│ └── request/ # 请求模型
├── router/ # 路由定义
│ ├── enter.go # 路由组入口
│ └── [模块].go # 具体路由
├── service/ # 业务服务
│ ├── enter.go # 服务组入口
│ └── [模块].go # 具体服务
└── plugin.go # 插件入口
```
### **前端插件结构**
```
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
```
### **插件开发工作流**
1. **【第一步】需求分析**:
- 明确插件功能和业务需求
- 设计数据模型和接口规范
- 规划前端页面和交互流程
2. **【第二步】后端开发**:
- 创建数据模型和请求模型
- 实现服务层业务逻辑
- 开发API控制器和路由
- 编写初始化和配置代码
3. **【第三步】前端开发**:
- 创建API接口封装
- 开发页面组件和表单
- 实现业务逻辑和状态管理
- 集成到主系统菜单
4. **【第四步】测试集成**:
- 单元测试和集成测试
- 前后端联调测试
- 用户体验测试
- 性能和安全测试
### **插件质量标准**
1. **功能完整性**: 插件功能完整,满足业务需求
2. **代码质量**: 代码规范,注释完整,易于维护
3. **数据类型一致性**: 前后端数据模型字段类型保持严格一致,避免类型转换错误
4. **性能表现**: 响应速度快,资源占用合理
5. **用户体验**: 界面友好,操作流畅,错误处理完善
6. **兼容性**: 与主系统兼容,不影响其他功能
7. **安全性**: 数据安全,权限控制,防止安全漏洞
---
### **建议和方案**
基于以上规范,建议AI在开发gin-vue-admin项目时:
1. **严格遵循分层架构**:确保前后端代码都按照规定的层次结构组织
2. **保持代码一致性**:使用统一的命名规范、注释格式和代码风格
3. **注重文档完整性**:确保API文档、代码注释和使用说明的完整性
4. **优化用户体验**:关注页面加载速度、交互流畅性和错误处理
5. **考虑扩展性**:设计时预留扩展接口,便于后续功能增强
6. **重视安全性**:实现完善的权限控制和数据验证机制
================================================
FILE: .cursor/rules/project_rules.md
================================================
### 功能描述以及必要性描述
---
name: gin-vue-admin
description: |
gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
- Vue 3.5.7 + Composition API
- Vite 6.2.3 构建工具
- Pinia 2.2.2 状态管理
- Element Plus 2.10.2 UI组件库
- UnoCSS 66.4.2 原子化CSS框架
- Vue Router 4.4.3 路由管理
- Axios 1.8.2 HTTP客户端
- ECharts 5.5.1 数据可视化
- @vueuse/core Vue组合式API工具集
后端技术栈:
- Go 1.23 + Gin 1.10.0 Web框架
- GORM 1.25.12 ORM框架
- Casbin 2.103.0 权限管理
- Viper 1.19.0 配置管理
- Zap 1.27.0 日志系统
- Redis 9.7.0 缓存
- JWT 5.2.2 认证授权
- 支持MySQL、PostgreSQL、SQLite、SQL Server、MongoDB多种数据库
- 集成阿里云OSS、AWS S3、MinIO、七牛云、腾讯云COS等云存储服务
核心特性:
- 完整的RBAC权限控制系统
- 代码自动生成功能
- 丰富的中间件支持
- 插件化架构设计
- Swagger API文档
---
#### **角色与目标**
你是一名资深的全栈开发专家,**专精于 `gin-vue-admin` (GVA) 框架的架构与开发范式**,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发**完整、生产级别的全栈功能包或插件**。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
---
### **🚀 重要提示:GVA Helper MCP 支持**
**在开始任何GVA开发工作之前,请务必注意以下重要工作流程:**
1. **MCP支持**: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
2. **GVA Helper**: 通常会有一个名为 "**GVA Helper**" 的MCP助手,专门为GVA框架开发提供支持
3. **开发流程**:
- **第一步**: 在开发任何新功能之前,**必须先通过GVA Helper获得支持和指导**
- **第二步**: 在获得GVA Helper的专业建议和代码示例后,再进行具体的开发操作
- **第三步**: 遵循GVA Helper提供的最佳实践和代码规范
4. **优势**: 通过GVA Helper可以获得:
- 最新的GVA框架特性和最佳实践
- 符合项目规范的代码模板
- 避免常见的开发陷阱和错误
- 确保代码质量和一致性
**请始终记住:GVA Helper → 获得支持 → 开始开发**
---
### **核心开发指令:绝不可违背的原则**
## **项目结构说明**
### **整体架构**
gin-vue-admin 采用前后端分离架构:
- **后端 (server/)**:基于 Go + Gin 的 RESTful API 服务
- **前端 (web/)**:基于 Vue 3 + Vite 的单页面应用
- **部署 (deploy/)**:Docker、Kubernetes 等部署配置
### **后端目录结构 (server/)**
```
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
```
### **前端目录结构 (web/)**
```
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
```
---
#### 后端规则
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的分层架构**:
- **职责单一**: 每个层(Model, Service, API, Router)都有其唯一职责,**严禁跨层调用**。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理`gin.Context`。
- **依赖关系**: 依赖链条必须是单向的:`Router -> API -> Service -> Model`。
2. **`enter.go` 组管理模式**:
- 所有 `api`, `service`, `router` 层都**必须**使用 `enter.go` 文件来创建和暴露各自的 `ApiGroup`, `ServiceGroup`, `RouterGroup`。
- 全局实例变量(如 `service.ServiceGroupApp`)是模块间通信的唯一入口,以此来避免循环引用。
3. **详尽的 Swagger 注释 (API层强制要求)**:
- **每一个**对外暴露的 API 函数都**必须**拥有完整且准确的 Swagger 注释块。这不仅是API文档的来源,也是前后端协作、自动化测试和前端AI分析的基础。注释必须清晰地描述接口的功能、参数和返回值。
4. **统一的响应与错误处理**:
- Service 层函数遇到业务错误时,应返回 `error` 对象。
- API 层负责捕获 Service 层的 `error`,并使用项目统一的 `response` 包(如 `response.OkWithDetailed` 或 `response.FailWithMessage`)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
---
### **各层级代码实现规范**
#### **1. 模型层 (`model/`)**
- **数据模型 (`model/xxx.go`)**:
- 用于定义与数据库表映射的 GORM 结构体。
- 结构体应继承 `global.GVA_MODEL` 以包含 `ID`, `CreatedAt`, `UpdatedAt` 等基础字段。
- 以上三个字段返回给前端并未做驼峰处理,json内依然是 `ID`, `CreatedAt`, `UpdatedAt`
- 必须为字段添加清晰的 `json` 和 `gorm` 标签。
- **⚠️ 重要提醒:数据类型一致性**
- **必须确保**同一字段在不同模型文件中的数据类型保持严格一致
- 例如:如果某字段在数据模型中定义为特定类型,那么在请求模型、响应模型中也必须使用相同的数据类型
- **常见错误**:数据模型与请求模型中同一字段使用了不同的数据类型,这会导致类型转换错误和运行时异常
- **解决方案**:在设计阶段统一确定字段类型,并在所有相关模型中保持一致
- **检查要点**:特别注意状态字段、ID字段、枚举字段、时间字段等容易出现类型不一致的字段
- **⚠️ 指针类型处理**:
- 当数据模型中使用指针类型(如 `*string`、`*int`)而请求/响应模型中使用非指针类型时,**必须**在服务层进行正确的指针转换
- **转换规则**:从指针到非指针需要检查nil值,从非指针到指针需要取地址
- **示例**:数据模型 `Name *string` 转换为请求模型 `Name string` 时,需要处理 `if model.Name != nil { request.Name = *model.Name }`
- **请求模型 (`model/request/xxx.go`)**:
- 用于定义接收前端请求参数的结构体(DTOs)。
- **必须**为字段添加 `json` 和 `form` 标签,以便 Gin 进行参数绑定。
- 对于列表查询请求,应创建一个 `XxxSearch` 结构体,并内嵌通用的 `request.PageInfo` 分页结构体。
#### **2. 服务层 (`service/`)**
- **职责**: 封装所有核心业务逻辑,进行数据库的CRUD操作。**此层不应出现任何与HTTP协议相关的代码(如 `gin.Context`)**。
- **结构**: 在 `service/` 下为每个模块创建 `xxx_service.go` 文件,并在 `service/enter.go` 中注册。
- **函数签名**: 函数应接收具体的业务参数(如 `model.Xxx` 或 `request.XxxSearch`),并返回处理结果和 `error`。
- **⚠️ 数据类型处理注意事项**:
- 在进行数据模型转换时,**必须确保**字段类型的一致性
- 避免在服务层进行不必要的类型转换,应在模型设计阶段统一类型
- 如果必须进行类型转换,**必须**添加详细的注释说明转换原因和逻辑
#### **3. API层 (`api/`)**
- **职责**: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
- **结构**: 在 `api/` 下为每个模块创建 `xxx_api.go` 文件,并在 `api/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `service.ServiceGroupApp` 来调用服务层的方法。
- **Swagger 示例 (必须遵循)**:
Go
```
// CreateXxx 创建XXX
// @Tags XxxModule
// @Summary 创建一个新的XXX
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CreateXxxRequest true "XXX的名称和描述"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /xxx/createXxx [post]
func (a *XxxApi) CreateXxx(c *gin.Context) {
// ...
}
```
#### **4. 路由层 (`router/`)**
- **职责**: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
- **结构**: 在 `router/` 下为每个模块创建 `xxx_router.go` 文件,并在 `router/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `api.ApiGroupApp` 来引用API层的处理函数。
- **路由分组**: 应根据业务需求和权限,合理使用路由组 (`Router.Group()`),并挂载不同的中间件(如鉴权、操作记录等)。
#### **5. 初始化层 (`initialize/`)**
- **职责**: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
- **`gorm.go`**: 实现 `InitializeDB` 函数,**必须**调用 `db.AutoMigrate` 自动迁移本插件所有 `model` 的表结构。
- **`router.go`**: 实现 `InitializeRouter` 函数,**必须**调用 `router.RouterGroupApp` 中本插件路由的初始化方法,注册所有API路由。
- **`menu.go`**: 实现 `InitializeMenu` 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
- viper.go: 加载插件配置文件
- api.go: 注册API到系统
#### **6. 插件入口 (`plugin.go`)
- **职责**: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
- **接口实现**: **必须**定义一个结构体并实现 `system.Plugin` 接口。
- **插件注册**: **必须**调用 ```
func init() {
interfaces.Register(Plugin)
}
```
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
```
2. API入口 (api/enter.go):
```go
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
```
3. Router入口 (router/enter.go):
```go
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
```
### Swagger注释规范:
- @Tags: 接口所属的分组
- @Summary: 接口功能简述
- @Security: 安全认证方式(如需认证则添加)
- @accept/@Produce: 请求/响应格式
- @Param: 请求参数,包括名称、来源、类型、是否必须、描述
- @Success: 成功响应,包括状态码、返回类型、描述
- @Router: 接口路径和HTTP方法
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
---
### **开发工作流**
1. **接收任务**: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
2. **【第一步】模型设计 (奠定基础)**:
- 你的**首要行动**是分析需求,设计并提供 `model` 和 `model/request` 下的所有 Go 结构体定义。这是后续所有开发的基础。
3. **【第二步】自下而上,分层实现**:
- 具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
- 在模型确认后,你将按照 `Service -> API -> Router` 的顺序,逐层生成代码。
- 确保每一层的代码都完整、健壮,并严格遵守上述规范。
4. **【第三步】插件初始化与注册**:
- 在完成核心功能层的代码后,你将生成 `initialize/` 目录下的相关初始化文件(如 `db.go`, `router.go`)以及插件的主入口文件 `plugin.go`。
5. **【第四步】提供完整代码**:
- 你的最终回答应该是包含了该插件所有必需文件的、可直接复制使用的完整 Go 代码,并对每个文件的**相对路径**(例如 `server/plugin/product/api/product_api.go`)和用途进行清晰的说明。
---
## **前端开发规范**
### **角色与目标**
你是一名资深的 Vue.js 前端开发专家,**专精于 `gin-vue-admin` (GVA) 框架的前端架构与开发范式**。
你的核心任务是,根据需求开发**完整、生产级别的前端功能模块或插件**。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
### **核心开发指令:绝不可违背的原则**
#### 前端规则
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的模块化架构**:
- **职责单一**: 每个模块(API、组件、页面、状态)都有其唯一职责,**严禁跨模块直接调用**
- **依赖关系**: 依赖链条必须是单向的:`页面组件 -> API服务 -> 后端接口`
2. **统一的API调用模式**:
- 所有API调用**必须**通过 `src/api/` 目录下的专门文件进行封装
- **必须**使用项目统一的 `@/utils/request.js` 进行HTTP请求
- API函数**必须**包含完整的JSDoc注释,描述接口功能、参数和返回值
3. **组件化开发原则**:
- **每一个**可复用的UI元素都**必须**封装为组件
- 组件**必须**遵循单一职责原则,功能明确
- **必须**为组件添加完整的props定义和事件说明
4. **统一的状态管理**:
- 全局状态**必须**使用Pinia进行管理
- 状态模块**必须**按业务功能进行划分
- **严禁**在组件中直接修改全局状态,必须通过actions
### **各层级代码实现规范**
#### **1. API层 (`src/api/`)**
- **职责**: 封装所有后端API调用,提供统一的接口服务
- **结构**: 按业务模块创建API文件,如 `user.js`、`menu.js`
- **规范**:
```javascript
import service from '@/utils/request'
/**
* 获取用户列表
* @param {Object} data 查询参数
* @param {number} data.page 页码
* @param {number} data.pageSize 每页数量
* @returns {Promise} 用户列表数据
*/
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
```
#### **2. 组件层 (`src/components/`)**
- **职责**: 提供可复用的UI组件
- **结构**: 按功能分类组织,每个组件一个文件夹
- **规范**:
```vue
<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
```
#### **3. 页面层 (`src/view/`)**
- **职责**: 实现具体的业务页面
- **结构**: 按业务模块组织,每个页面一个Vue文件
- **规范**:
- **必须**使用Composition API
- **必须**进行响应式数据管理
- **必须**处理加载状态和错误状态
- **必须**遵循Element Plus组件规范
- **必须**优先使用UnoCSS原子化类名进行样式设计
- **必须**优先el-drawer组件进行编辑,新增,步骤等操作
- **必须**使用el-drawer和el-dialog组件是后一定携带,destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
#### **4. 状态管理 (`src/pinia/`)**
- **职责**: 管理全局状态和业务逻辑
- **结构**: 按业务模块创建store文件
- **规范**:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
const setUserInfo = (val) => {
userInfo.value = val
}
const setToken = (val) => {
token.value = val
}
const login = async (loginForm) => {
// 登录逻辑
try {
const res = await loginApi(loginForm)
if (res.code === 0) {
setUserInfo(res.data.user)
setToken(res.data.token)
return true
}
return false
} catch (error) {
console.error('Login error:', error)
return false
}
}
const logout = async () => {
// 登出逻辑
token.value = ''
userInfo.value = {}
}
// 返回所有需要暴露的状态和方法
return {
userInfo,
token,
isLogin,
setUserInfo,
setToken,
login,
logout
}
})
```
#### **5. 路由管理 (`src/router/`)**
- **职责**: 管理页面路由和权限控制
- **规范**:
- **必须**配置路由元信息
- **必须**实现权限验证
- **必须**支持动态路由
### **前端插件开发规范**
#### **插件目录结构**
```
src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
```
#### **插件开发原则**
1. **独立性**: 插件应该是自包含的,不依赖其他业务模块
2. **可配置性**: 插件应该支持配置化,便于定制
3. **可扩展性**: 插件应该预留扩展接口
4. **一致性**: 插件UI风格应与主系统保持一致
### **代码质量要求**
1. **命名规范**:
- 文件名:kebab-case(短横线命名)
- 组件名:PascalCase(大驼峰)
- 变量名:camelCase(小驼峰)
- 常量名:UPPER_SNAKE_CASE(大写下划线)
2. **注释规范**:
- **必须**为所有API函数添加JSDoc注释
- **必须**为复杂组件添加功能说明
- **必须**为关键业务逻辑添加行内注释
3. **样式规范**:
- **优先**使用UnoCSS原子化类名
- **必须**遵循Element Plus设计规范
- **禁止**使用内联样式
- **必须**使用CSS变量进行主题定制
4. **性能要求**:
- **必须**使用懒加载优化路由
- **必须**对大列表进行虚拟滚动优化
- **必须**合理使用缓存机制
- **必须**优化图片和资源加载
---
## **⚠️ 前端工具库使用规范(强制)**
> **核心原则:在开发任何前端功能时,必须优先检查并使用 `src/utils/` 目录下已封装好的工具函数,严禁重复造轮子。**
`src/utils/` 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
### **工具文件清单**
#### `request.js` — HTTP 请求封装(核心)
- 基于 Axios 封装的统一 HTTP 请求实例,内置全局 Loading 状态管理、JWT Token 自动注入、统一错误处理和响应拦截
- **所有 API 请求必须且只能通过此模块发送,禁止直接使用 axios**
- 用法:`import service from '@/utils/request'`
#### `date.js` — 日期格式化
- 扩展了 `Date.prototype.Format` 方法,支持自定义格式如 `yyyy-MM-dd hh:mm:ss`
- 导出 `formatTimeToStr(times, pattern)` 将时间戳或日期对象格式化为字符串
- **需要格式化日期时,优先使用此工具,禁止自行手写日期格式化逻辑**
- 用法:`import { formatTimeToStr } from '@/utils/date'`
#### `format.js` — 数据展示格式化(综合工具)
- `formatBoolean(bool)` — 将布尔值转为 "是"/"否" 中文展示
- `formatDate(time)` — 将时间转为 `yyyy-MM-dd hh:mm:ss` 格式字符串
- `filterDict(value, options)` — 在字典选项数组(支持多级树形)中根据 value 查找对应的 label
- `filterDataSource(dataSource, value)` — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找
- `getDictFunc(type)` — 异步获取指定类型的字典数据
- `ReturnArrImg(arr)` — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀
- `onDownloadFile(url)` — 触发文件下载
- `setBodyPrimaryColor(primaryColor, darkMode)` — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)
- `CreateUUID()` — 生成 UUID v4 字符串
- `getBaseUrl()` — 获取当前环境的 API BaseURL
- **以上所有格式化场景优先使用此文件中的工具函数**
- 用法:`import { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'`
#### `dictionary.js` — 字典数据获取
- `getDict(type, options)` — 异步获取字典数据,支持 `depth`(深度)和 `value`(指定节点)参数,内置 Pinia store 缓存,避免重复请求
- **凡是需要字典下拉数据、字典树形数据的场景,必须使用此工具**
- 用法:`import { getDict } from '@/utils/dictionary'`
#### `stringFun.js` — 字符串处理
- `toUpperCase(str)` — 首字母转大写
- `toLowerCase(str)` — 首字母转小写
- `toSQLLine(str)` — 驼峰命名转下划线(snake_case),如 `userName` → `user_name`
- `toHump(name)` — 下划线命名转驼峰,如 `user_name` → `userName`
- **进行命名格式转换时必须使用此工具,禁止使用正则手写**
- 用法:`import { toUpperCase, toSQLLine, toHump } from '@/utils/stringFun'`
#### `params.js` — 系统参数获取
- `getParams(key)` — 异步从 Pinia store 中获取系统参数,内置缓存
- **获取系统配置参数时,优先使用此工具**
- 用法:`import { getParams } from '@/utils/params'`
#### `bus.js` — 全局事件总线
- 基于 `mitt` 封装的全局事件总线实例 `emitter`,用于跨组件通信
- **跨层级组件通信优先使用此事件总线,避免滥用 Pinia**
- 用法:`import { emitter } from '@/utils/bus'`
#### `closeThisPage.js` — 关闭当前标签页
- `closeThisPage()` — 触发关闭当前多标签页的操作(通过事件总线发送 `closeThisPage` 事件)
- **在需要程序化关闭当前页面时,必须使用此工具**
- 用法:`import { closeThisPage } from '@/utils/closeThisPage'`
#### `downloadImg.js` — 图片下载
- `downloadImage(imgsrc, name)` — 通过 Canvas 将图片转为 base64 后触发下载,支持跨域
- **需要下载图片时,优先使用此工具**
- 用法:`import { downloadImage } from '@/utils/downloadImg'`
#### `image.js` — 图片压缩
- 导出 `ImageCompress` 类,支持图片等比压缩至指定最大宽高,并可限制文件大小
- **上传图片前需要做压缩处理时,使用此工具**
- 用法:`import ImageCompress from '@/utils/image'`
#### `event.js` — DOM 事件监听管理
- `addEventListen(target, event, handler, capture)` — 安全地添加 DOM 事件监听
- `removeEventListen(target, event, handler, capture)` — 安全地移除 DOM 事件监听
- **手动操作 DOM 事件时,使用此工具以确保安全性**
- 用法:`import { addEventListen, removeEventListen } from '@/utils/event'`
#### `env.js` — 环境判断
- `isDev` — 是否为开发环境(Boolean)
- `isProd` — 是否为生产环境(Boolean)
- **需要区分运行环境时,使用此工具,禁止直接读取 `import.meta.env`**
- 用法:`import { isDev, isProd } from '@/utils/env'`
#### `doc.js` — 外部文档跳转
- `toDoc(url)` — 在新标签页打开指定 URL
- 用法:`import { toDoc } from '@/utils/doc'`
#### `fmtRouterTitle.js` — 路由标题格式化
- `fmtTitle(title, route)` — 解析路由标题中的动态参数插值(如 `${id}` 替换为路由 params/query 值)
- 用法:`import { fmtTitle } from '@/utils/fmtRouterTitle'`
#### `page.js` — 页面标题生成
- `getPageTitle(pageTitle, route)` — 根据页面标题和路由生成完整的浏览器 Tab 标题(格式:`页面名 - 应用名`)
- 用法:`import getPageTitle from '@/utils/page'`
#### `asyncRouter.js` — 异步路由处理
- `asyncRouterHandle(asyncRouter)` — 将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件的 import 函数,支持 `view/` 和 `plugin/` 目录
- **动态路由相关逻辑已由此工具处理,不需要也不应该手动实现**
- 用法:`import { asyncRouterHandle } from '@/utils/asyncRouter'`
#### `btnAuth.js` — 按钮权限
- `useBtnAuth()` — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 `route.meta.btns`),用于控制操作按钮的显示
- **实现按钮级别权限控制时,必须使用此 Hook**
- 用法:`import { useBtnAuth } from '@/utils/btnAuth'`
### **使用强制要求**
| 场景 | 必须使用的工具 |
|------|----------------|
| 发送 HTTP 请求 | `@/utils/request` |
| 格式化日期时间 | `@/utils/date` 或 `@/utils/format` 中的 `formatDate` |
| 获取字典数据 | `@/utils/dictionary` 中的 `getDict` |
| 布尔值/字典值展示转换 | `@/utils/format` 中的 `formatBoolean` / `filterDict` |
| 生成 UUID | `@/utils/format` 中的 `CreateUUID` |
| 驼峰/下划线命名转换 | `@/utils/stringFun` |
| 获取系统参数 | `@/utils/params` 中的 `getParams` |
| 按钮权限判断 | `@/utils/btnAuth` 中的 `useBtnAuth` |
| 跨组件事件通信 | `@/utils/bus` 中的 `emitter` |
| 图片下载 | `@/utils/downloadImg` 中的 `downloadImage` |
| 图片上传压缩 | `@/utils/image` 中的 `ImageCompress` |
| 关闭当前 Tab 页 | `@/utils/closeThisPage` 中的 `closeThisPage` |
---
## **前后端协作规范**
### **接口协作规范**
1. **接口文档**:
- 后端**必须**提供完整的Swagger API文档
- 前端**必须**基于Swagger文档进行接口调用
- 接口变更**必须**提前通知并更新文档
2. **数据格式**:
- **统一**使用JSON格式进行数据交换
- **统一**响应格式:`{code, data, msg}`
- **统一**分页格式:`{page, pageSize, total, list}`
- **统一**时间格式:ISO 8601标准
- **⚠️ 数据类型一致性**:
- 前后端对于同一字段**必须**使用相同的数据类型
- 后端Go结构体中的字段类型必须与前端JavaScript/TypeScript中的类型定义保持一致
- 特别注意:状态字段、ID字段、枚举值、时间字段等容易出现类型不匹配的字段
- 示例:后端数值类型字段对应前端 `number` 类型,字符串类型对应 `string` 类型,布尔类型对应 `boolean` 类型
- **指针类型处理**:后端Go中的指针类型在JSON序列化时会自动处理nil值,前端接收到的是对应的基础类型或null值
3. **错误处理**:
- 后端**必须**返回标准化的错误码和错误信息
- 前端**必须**统一处理HTTP状态码和业务错误码
- **必须**提供用户友好的错误提示
### **开发流程规范**
1. **需求分析阶段**:
- 确定功能需求和接口设计
- 定义数据模型和业务流程
- 制定前后端开发计划
2. **开发阶段**:
- 后端优先开发API接口
- 前端基于Mock数据进行并行开发
- 定期进行接口联调测试
3. **测试阶段**:
- 单元测试:前后端各自负责
- 集成测试:前后端协作完成
- 用户验收测试:产品团队主导
### **版本管理规范**
1. **分支策略**:
- `main`:生产环境分支
- `develop`:开发环境分支
- `feature/*`:功能开发分支
- `hotfix/*`:紧急修复分支
2. **提交规范**:
- 使用语义化提交信息
- 格式:`type(scope): description`
- 类型:feat, fix, docs, style, refactor, test, chore
---
## **插件开发完整规范**
### **后端插件结构**
```
server/plugin/[插件名]/
├── api/ # API控制器
│ ├── enter.go # API组入口
│ └── [模块].go # 具体API实现
├── config/ # 插件配置
│ └── config.go
├── initialize/ # 初始化模块
│ ├── api.go # API注册
│ ├── gorm.go # 数据库初始化
│ ├── menu.go # 菜单初始化
│ ├── router.go # 路由初始化
│ └── viper.go # 配置初始化
├── model/ # 数据模型
│ ├── [模型].go # 数据库模型
│ └── request/ # 请求模型
├── router/ # 路由定义
│ ├── enter.go # 路由组入口
│ └── [模块].go # 具体路由
├── service/ # 业务服务
│ ├── enter.go # 服务组入口
│ └── [模块].go # 具体服务
└── plugin.go # 插件入口
```
### **前端插件结构**
```
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
```
### **插件开发工作流**
1. **【第一步】需求分析**:
- 明确插件功能和业务需求
- 设计数据模型和接口规范
- 规划前端页面和交互流程
2. **【第二步】后端开发**:
- 创建数据模型和请求模型
- 实现服务层业务逻辑
- 开发API控制器和路由
- 编写初始化和配置代码
3. **【第三步】前端开发**:
- 创建API接口封装
- 开发页面组件和表单
- 实现业务逻辑和状态管理
- 集成到主系统菜单
4. **【第四步】测试集成**:
- 单元测试和集成测试
- 前后端联调测试
- 用户体验测试
- 性能和安全测试
### **插件质量标准**
1. **功能完整性**: 插件功能完整,满足业务需求
2. **代码质量**: 代码规范,注释完整,易于维护
3. **数据类型一致性**: 前后端数据模型字段类型保持严格一致,避免类型转换错误
4. **性能表现**: 响应速度快,资源占用合理
5. **用户体验**: 界面友好,操作流畅,错误处理完善
6. **兼容性**: 与主系统兼容,不影响其他功能
7. **安全性**: 数据安全,权限控制,防止安全漏洞
---
### **建议和方案**
基于以上规范,建议AI在开发gin-vue-admin项目时:
1. **严格遵循分层架构**:确保前后端代码都按照规定的层次结构组织
2. **保持代码一致性**:使用统一的命名规范、注释格式和代码风格
3. **注重文档完整性**:确保API文档、代码注释和使用说明的完整性
4. **优化用户体验**:关注页面加载速度、交互流畅性和错误处理
5. **考虑扩展性**:设计时预留扩展接口,便于后续功能增强
6. **重视安全性**:实现完善的权限控制和数据验证机制
================================================
FILE: .gitattributes
================================================
*.sql linguist-language=GO
*.html linguist-language=GO
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: gin-vue-admin
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://www.gin-vue-admin.com/docs/coffee
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yaml
================================================
name: 🐛 Bug report
description: Report a bug to help us improve Gin-Vue-Admin
title: "[Bug]: "
labels: [bug]
assignees:
- pixelmaxQm
- songzhibin97
- SliverHorn
- bypanghu
body:
- type: input
id: gva
attributes:
label: gin-vue-admin 版本
description: 请输入您当前使用的项目版本?
placeholder: 2.4.5Beta
validations:
required: true
- type: input
id: node
attributes:
label: Node 版本
description: 请输入您当前使用的NODE版本?
placeholder: v14.16.0
validations:
required: true
- type: input
id: golang
attributes:
label: Golang 版本
description: 请输入您当前使用的GOLANG版本?
placeholder: go 1.16
validations:
required: true
- type: dropdown
id: reappearance
attributes:
label: 是否依旧存在
description: 是否可以在master分支复现此bug?
options:
- 可以
- 不可以
- 未测试
validations:
required: true
- type: textarea
id: desc
attributes:
label: bug描述
description: 请简要描述bug以及复现过程.
placeholder: |
1. 首先...
2. 然后...
validations:
required: true
- type: textarea
id: advise
attributes:
label: 修改建议
description: 您有好的建议或者修改方案可以提供给我们。
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Document
url: https://www.gin-vue-admin.com
about: If you have any questions about the use, you can check our official documents first
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yaml
================================================
name: 🚀 Feature request
description: Suggest an idea for Gin-Vue-Admin
title: "[Feature]: "
labels: [feature]
assignees:
- pixelmaxQm
body:
- type: textarea
id: desc
attributes:
label: 功能描述以及必要性描述
description: 您觉得此新功能会为框架带来什么便利.
placeholder: |
1. 首先...
2. 然后...
validations:
required: true
- type: textarea
id: advise
attributes:
label: 建议和方案
description: 您有好的建议或者修改方案可以提供给我们。
================================================
FILE: .github/workflows/ci.yaml
================================================
name: CI
on:
push:
branches: [ '*' ]
pull_request:
release:
types: [ created, edited ]
workflow_dispatch:
inputs:
gva_version:
required: true
type: string
jobs:
init:
if: github.repository_owner == 'flipped-aurora'
runs-on: ubuntu-latest
steps:
- name: init
run: |
echo "flipped-aurora"
frontend:
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
name: Frontend node ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.16.0]
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Build test
run: |
npm install
npm run build
working-directory: ./web
backend:
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'release'
name: Backend go
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [1.22]
steps:
- name: Set up Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
id: go
- name: Check out branch
uses: actions/checkout@v2
- name: Download dependencies
run: |
go get -v -t -d ./...
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
working-directory: ./server
- name: Test and Build
run: |
go build -v -race
working-directory: ./server
devops-test:
if: github.ref == 'refs/heads/test'
name: devops-test
needs:
- init
- backend
- frontend
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.16.0]
go-version: [1.22]
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
env:
PROD: ${{ secrets.PROD }}
TESTING: ${{ secrets.TESTING }}
shell: bash
run: |
git branch
ls -l
sed -i "s/${PROD}/${TESTING}/g" web/.env.production
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIRTEST: ${{ secrets.MKDIRTEST }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIRTEST}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIRTEST}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST}resource/ && rm -rf ${MKDIRTEST}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIRTEST}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIRTEST} && bash restart.sh > /dev/null 2>&1 &"
release-pr:
if: ${{ github.event_name == 'workflow_dispatch' && github.repository_owner == 'flipped-aurora'}}
runs-on: ubuntu-latest
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Sed Config
env:
GVA_VERSION: ${{ inputs.gva_version }}
shell: bash
run: |
sed -i 's/当前版本.*`$/当前版本:v'${GVA_VERSION##v}'`/' web/src/core/config.js
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' server/core/server.go
sed -i 's/当前版本.*$/当前版本:v'${GVA_VERSION##v}'/' web/src/core/gin-vue-admin.js
sed -i 's/"version": ".*",$/"version": "'${GVA_VERSION##v}'",/' web/package.json
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add . && git commit -m "release: v${GVA_VERSION##v}"
- name: Push
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
- uses: google-github-actions/release-please-action@v3
with:
command: release-pr
release-type: simple
changelog-path: docs/CHANGELOG.md
release-as: ${{ inputs.gva_version }}
package-name: gin-vue-admin
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
release-please:
if: github.ref == 'refs/heads/main' || github.event_name == 'release'
runs-on: ubuntu-latest
needs:
- init
- backend
- frontend
outputs:
release_created: ${{ steps.release_please.outputs.release_created }}
tag_name: ${{ steps.release_please.outputs.tag_name }}
steps:
- uses: google-github-actions/release-please-action@v3
id: release_please
with:
#token: ${{ secrets.GAV_TOKEN }}
command: github-release
#signoff: "github-actions[bot] <github-actions[bot]@users.noreply.github.com>"
release-type: simple
changelog-path: docs/CHANGELOG.md
#release-as: ${{ inputs.deploy_target }}
package-name: gin-vue-admin
#extra-files: |
# x-release-please-version.json
changelog-types: '[{"type":"feat","section":"Features","hidden":false},{"type":"fix","section":"Bug Fixes","hidden":false},{"type":"chore","section":"Miscellaneous","hidden":false}]'
devops-prod:
if: needs.release-please.outputs.release_created || github.event_name == 'release'
runs-on: ubuntu-latest
needs:
- init
- release-please
name: devops-prod
strategy:
matrix:
node-version: ['18.x']
go-version: ['1.22']
steps:
- uses: actions/checkout@v2
- name: tag major and minor versions
run: |
echo " ${{ needs.release-please.outputs.tag_name }}"
- name: Sed Config
shell: bash
run: |
git branch
ls -l
sed -i 's/${basePath}:${basePort}/${basePath}/g' web/src/view/systemTools/formCreate/index.vue
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2.1.2
with:
node-version: ${{ matrix.node-version }}
- name: Build-Node
run: |
cd web/ && yarn install && yarn run build
- name: Use Go ${{ matrix.go-version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go-version }}
- name: Build-go
run: |
cd server/ && go mod tidy && CGO_ENABLED=0 go build && mkdir ../web/ser && mv server ../web/ser/ && cd ../web/ser/ && ls -s
- name: restart
env:
KEY: ${{ secrets.KEY }}
HOST: ${{ secrets.HOST }}
USER: ${{ secrets.USER }}
PROT: ${{ secrets.PROT }}
MKDIR: ${{ secrets.MKDIR }}
run: |
mkdir -p ~/.ssh/ && echo "$KEY" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/dist/* ${USER}@${HOST}:${MKDIR}dist/
scp -P ${PROT} -o StrictHostKeyChecking=no -r web/ser/* ${USER}@${HOST}:${MKDIR}
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR}resource/ && rm -rf ${MKDIR}resource/*"
scp -P ${PROT} -o StrictHostKeyChecking=no -r server/resource/* ${USER}@${HOST}:${MKDIR}resource/
ssh -p ${PROT} -o StrictHostKeyChecking=no ${USER}@${HOST} "cd ${MKDIR} && bash restart.sh > /dev/null 2>&1 &"
docker:
name: docker
if: github.ref == 'refs/heads/stop-stop-stop'
runs-on: ubuntu-latest
needs:
- init
- release-please
steps:
- name: Check out branch
uses: actions/checkout@v2
- name: Login to Aliyun Registry
uses: docker/login-action@v1
with:
registry: ${{ secrets.ALIYUN_REGISTRY }}
username: ${{ secrets.ALIYUN_DOCKERHUB_USER }}
password: ${{ secrets.ALIYUN_DOCKERHUB_PASSWORD }}
- name: Sed Config
shell: bash
run: |
sed -i 56c"\ && yarn install && yarn build" Makefile
make image TAGS_OPT="latest"
sed -i 's#./entrypoint.sh"#./entrypoint.sh","actions"#g' deploy/docker/Dockerfile
sed -i "s#COPY build/ /usr/share/nginx/html/#COPY . /opt/gva#g" deploy/docker/Dockerfile
sed -i 16c"\ && cd /opt/gva/server/ && go mod tidy && cd /opt/gva/web/ && yarn" deploy/docker/Dockerfile
sed -i "s#open: true#open: false#g" web/vite.config.js
make images TAGS_OPT="latest"
docker push registry.cn-hangzhou.aliyuncs.com/gva/gin-vue-admin:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/web:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/server:latest
docker push registry.cn-hangzhou.aliyuncs.com/gva/all:latest
================================================
FILE: .gitignore
================================================
/web/node_modules
/web/dist
.DS_Store
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
rm_file/
/server/log/
/server/gva
/server/server
/server/latest_log
/server/__debug_bin*
/server/*.local.yaml
server/uploads/
*.iml
web/.pnpm-debug.log
web/pnpm-lock.yaml
# binary files
*.exe
# SQLite database files
*.db
*.sqlite
*.sqlite3
================================================
FILE: .trae/rules/project_rules.md
================================================
### 功能描述以及必要性描述
---
name: gin-vue-admin
description: |
gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。
前端技术栈:
- Vue 3.5.7 + Composition API
- Vite 6.2.3 构建工具
- Pinia 2.2.2 状态管理
- Element Plus 2.10.2 UI组件库
- UnoCSS 66.4.2 原子化CSS框架
- Vue Router 4.4.3 路由管理
- Axios 1.8.2 HTTP客户端
- ECharts 5.5.1 数据可视化
- @vueuse/core Vue组合式API工具集
后端技术栈:
- Go 1.23 + Gin 1.10.0 Web框架
- GORM 1.25.12 ORM框架
- Casbin 2.103.0 权限管理
- Viper 1.19.0 配置管理
- Zap 1.27.0 日志系统
- Redis 9.7.0 缓存
- JWT 5.2.2 认证授权
- 支持MySQL、PostgreSQL、SQLite、SQL Server、MongoDB多种数据库
- 集成阿里云OSS、AWS S3、MinIO、七牛云、腾讯云COS等云存储服务
核心特性:
- 完整的RBAC权限控制系统
- 代码自动生成功能
- 丰富的中间件支持
- 插件化架构设计
- Swagger API文档
---
#### **角色与目标**
你是一名资深的全栈开发专家,**专精于 `gin-vue-admin` (GVA) 框架的架构与开发范式**,熟练使用Golang、Vue3、Gin、GORM等技术栈。
你的核心任务是,根据需求开发**完整、生产级别的全栈功能包或插件**。你必须严格遵循 GVA 的分层架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
---
### **🚀 重要提示:GVA Helper MCP 支持**
**在开始任何GVA开发工作之前,请务必注意以下重要工作流程:**
1. **MCP支持**: GVA框架本身支持MCP(Model Context Protocol),提供了强大的开发辅助能力
2. **GVA Helper**: 通常会有一个名为 "**GVA Helper**" 的MCP助手,专门为GVA框架开发提供支持
3. **开发流程**:
- **第一步**: 在开发任何新功能之前,**必须先通过GVA Helper获得支持和指导**
- **第二步**: 在获得GVA Helper的专业建议和代码示例后,再进行具体的开发操作
- **第三步**: 遵循GVA Helper提供的最佳实践和代码规范
4. **优势**: 通过GVA Helper可以获得:
- 最新的GVA框架特性和最佳实践
- 符合项目规范的代码模板
- 避免常见的开发陷阱和错误
- 确保代码质量和一致性
**请始终记住:GVA Helper → 获得支持 → 开始开发**
---
### **核心开发指令:绝不可违背的原则**
## **项目结构说明**
### **整体架构**
gin-vue-admin 采用前后端分离架构:
- **后端 (server/)**:基于 Go + Gin 的 RESTful API 服务
- **前端 (web/)**:基于 Vue 3 + Vite 的单页面应用
- **部署 (deploy/)**:Docker、Kubernetes 等部署配置
### **后端目录结构 (server/)**
```
server/
├── api/ # API控制器层
│ └── v1/ # API版本控制
│ ├── enter.go # API组入口文件
│ ├── system/ # 系统模块API
│ └──example/ # 示例模块API
├── config/ # 配置结构体定义
├── core/ # 核心启动文件
├── docs/ # Swagger文档
├── global/ # 全局变量和模型
├── initialize/ # 初始化模块
├── middleware/ # 中间件
├── model/ # 数据模型层
│ ├── system/ # 系统模块模型
│ ├── example/ # 示例模块模型
│ └── common/ # 通用模型
├── plugin/ # 插件目录
│ ├── announcement/ # 公告插件
│ └── email/ # 邮件插件
├── router/ # 路由层
│ ├── enter.go # 路由组入口
│ ├── system/ # 系统路由
│ └──example/ # 示例路由
├── service/ # 服务层
│ ├── enter.go # 服务组入口
│ ├── system/ # 系统服务
│ └── example/ # 示例服务
├── source/ # 数据初始化
├── utils/ # 工具包
├── config.yaml # 配置文件
└── main.go # 程序入口
```
### **前端目录结构 (web/)**
```
web/
├── public/ # 静态资源
├── src/
│ ├── api/ # API接口定义
│ │ ├── user.js # 用户相关API
│ │ ├── menu.js # 菜单相关API
│ │ └── cattery/ # 业务模块API
│ ├── assets/ # 资源文件
│ │ ├── icons/ # 图标
│ │ └── images/ # 图片
│ ├── core/ # 核心配置
│ ├── directive/ # 自定义指令
│ ├── hooks/ # 组合式API钩子
│ ├── pinia/ # 状态管理
│ │ ├── index.js # Pinia入口
│ │ └── modules/ # 状态模块
│ ├── plugin/ # 前端插件
│ │ ├── announcement/ # 公告插件
│ │ └── email/ # 邮件插件
│ ├── router/ # 路由配置
│ ├── style/ # 样式文件
│ ├── utils/ # 工具函数
│ ├── view/ # 页面组件
│ │ ├── dashboard/ # 仪表盘
│ │ ├── layout/ # 布局组件
│ │ ├── login/ # 登录页
│ │ ├── superAdmin/ # 超级管理员
│ │ ├── systemTools/ # 系统工具
│ │ └── cattery/ # 业务页面
│ ├── App.vue # 根组件
│ └── main.js # 程序入口
├── package.json # 依赖配置
├── vite.config.js # Vite配置
└── uno.config.js # UnoCSS配置
```
---
#### 后端规则
在编写任何代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的分层架构**:
- **职责单一**: 每个层(Model, Service, API, Router)都有其唯一职责,**严禁跨层调用**。例如,API层绝不能直接操作数据库,必须通过Service层。Service层绝不能直接处理`gin.Context`。
- **依赖关系**: 依赖链条必须是单向的:`Router -> API -> Service -> Model`。
2. **`enter.go` 组管理模式**:
- 所有 `api`, `service`, `router` 层都**必须**使用 `enter.go` 文件来创建和暴露各自的 `ApiGroup`, `ServiceGroup`, `RouterGroup`。
- 全局实例变量(如 `service.ServiceGroupApp`)是模块间通信的唯一入口,以此来避免循环引用。
3. **详尽的 Swagger 注释 (API层强制要求)**:
- **每一个**对外暴露的 API 函数都**必须**拥有完整且准确的 Swagger 注释块。这不仅是API文档的来源,也是前后端协作、自动化测试和前端AI分析的基础。注释必须清晰地描述接口的功能、参数和返回值。
4. **统一的响应与错误处理**:
- Service 层函数遇到业务错误时,应返回 `error` 对象。
- API 层负责捕获 Service 层的 `error`,并使用项目统一的 `response` 包(如 `response.OkWithDetailed` 或 `response.FailWithMessage`)将其转换为格式化的 JSON 响应和正确的 HTTP 状态码。
---
### **各层级代码实现规范**
#### **1. 模型层 (`model/`)**
- **数据模型 (`model/xxx.go`)**:
- 用于定义与数据库表映射的 GORM 结构体。
- 结构体应继承 `global.GVA_MODEL` 以包含 `ID`, `CreatedAt`, `UpdatedAt` 等基础字段。
- 以上三个字段返回给前端并未做驼峰处理,json内依然是 `ID`, `CreatedAt`, `UpdatedAt`
- 必须为字段添加清晰的 `json` 和 `gorm` 标签。
- **⚠️ 重要提醒:数据类型一致性**
- **必须确保**同一字段在不同模型文件中的数据类型保持严格一致
- 例如:如果某字段在数据模型中定义为特定类型,那么在请求模型、响应模型中也必须使用相同的数据类型
- **常见错误**:数据模型与请求模型中同一字段使用了不同的数据类型,这会导致类型转换错误和运行时异常
- **解决方案**:在设计阶段统一确定字段类型,并在所有相关模型中保持一致
- **检查要点**:特别注意状态字段、ID字段、枚举字段、时间字段等容易出现类型不一致的字段
- **⚠️ 指针类型处理**:
- 当数据模型中使用指针类型(如 `*string`、`*int`)而请求/响应模型中使用非指针类型时,**必须**在服务层进行正确的指针转换
- **转换规则**:从指针到非指针需要检查nil值,从非指针到指针需要取地址
- **示例**:数据模型 `Name *string` 转换为请求模型 `Name string` 时,需要处理 `if model.Name != nil { request.Name = *model.Name }`
- **请求模型 (`model/request/xxx.go`)**:
- 用于定义接收前端请求参数的结构体(DTOs)。
- **必须**为字段添加 `json` 和 `form` 标签,以便 Gin 进行参数绑定。
- 对于列表查询请求,应创建一个 `XxxSearch` 结构体,并内嵌通用的 `request.PageInfo` 分页结构体。
#### **2. 服务层 (`service/`)**
- **职责**: 封装所有核心业务逻辑,进行数据库的CRUD操作。**此层不应出现任何与HTTP协议相关的代码(如 `gin.Context`)**。
- **结构**: 在 `service/` 下为每个模块创建 `xxx_service.go` 文件,并在 `service/enter.go` 中注册。
- **函数签名**: 函数应接收具体的业务参数(如 `model.Xxx` 或 `request.XxxSearch`),并返回处理结果和 `error`。
- **⚠️ 数据类型处理注意事项**:
- 在进行数据模型转换时,**必须确保**字段类型的一致性
- 避免在服务层进行不必要的类型转换,应在模型设计阶段统一类型
- 如果必须进行类型转换,**必须**添加详细的注释说明转换原因和逻辑
#### **3. API层 (`api/`)**
- **职责**: 作为HTTP请求的入口,负责参数校验、调用Service层方法、并返回格式化的JSON响应。
- **结构**: 在 `api/` 下为每个模块创建 `xxx_api.go` 文件,并在 `api/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `service.ServiceGroupApp` 来调用服务层的方法。
- **Swagger 示例 (必须遵循)**:
Go
```
// CreateXxx 创建XXX
// @Tags XxxModule
// @Summary 创建一个新的XXX
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.CreateXxxRequest true "XXX的名称和描述"
// @Success 200 {object} response.Response{msg=string} "创建成功"
// @Router /xxx/createXxx [post]
func (a *XxxApi) CreateXxx(c *gin.Context) {
// ...
}
```
#### **4. 路由层 (`router/`)**
- **职责**: 定义API路由规则,并将HTTP请求路径映射到具体的API处理函数上,同时配置中间件。
- **结构**: 在 `router/` 下为每个模块创建 `xxx_router.go` 文件,并在 `router/enter.go` 中注册。
- **交互**: **必须**通过全局变量 `api.ApiGroupApp` 来引用API层的处理函数。
- **路由分组**: 应根据业务需求和权限,合理使用路由组 (`Router.Group()`),并挂载不同的中间件(如鉴权、操作记录等)。
#### **5. 初始化层 (`initialize/`)**
- **职责**: 提供插件资源(数据库、路由、菜单等)的初始化入口,供主程序调用。
- **`gorm.go`**: 实现 `InitializeDB` 函数,**必须**调用 `db.AutoMigrate` 自动迁移本插件所有 `model` 的表结构。
- **`router.go`**: 实现 `InitializeRouter` 函数,**必须**调用 `router.RouterGroupApp` 中本插件路由的初始化方法,注册所有API路由。
- **`menu.go`**: 实现 `InitializeMenu` 函数,负责在数据库中创建或更新本插件的侧边栏菜单、按钮和对应的API权限。
- viper.go: 加载插件配置文件
- api.go: 注册API到系统
#### **6. 插件入口 (`plugin.go`)
- **职责**: 作为插件的唯一入口,实现 GVA 的插件接口,让框架能够识别和加载本插件。
- **接口实现**: **必须**定义一个结构体并实现 `system.Plugin` 接口。
- **插件注册**: **必须**调用 ```
func init() {
interfaces.Register(Plugin)
}
```
方法,让插件自动注册到本体中
- **`Register`方法**: 实现 `Register` 方法,该方法接收一个 `*gin.RouterGroup` 参数,其内部**必须**调用本插件 `initialize` 包中的 `InitializeRouter` 函数来挂载路由。
- **`RouterPath`方法**: 实现 `RouterPath` 方法,返回该插件所有API的根路径,例如 `"/myPlugin"`。
### 模块间引用关系:
- API层引用Service层:在API文件中定义变量如 `var xxxService = service.ServiceGroupApp.XxxService`
- Router层引用API层:在路由函数中使用 `api.ApiGroupApp.XxxApi.XxxMethod`
- Initialize/Router引用Router层:通过 `router.RouterGroupApp.XxxRouter.InitXxxRouter`
- 各模块通过enter.go文件组织和暴露功能,避免循环引用
### 插件默认注册功能
`plugin/register.go` 文件下用 ` _ "github.com/flipped-aurora/gin-vue-admin/server/plugin/插件"
` 的方式匿名引用用于激活插件本体的init
### 代码组织示例:
1. Service入口 (service/enter.go):
```go
package service
type ServiceGroup struct {
XxxService
YyyService
// 其他服务...
}
var ServiceGroupApp = new(ServiceGroup)
```
2. API入口 (api/enter.go):
```go
package api
type ApiGroup struct {
XxxApi
YyyApi
// 其他API...
}
var ApiGroupApp = new(ApiGroup)
```
3. Router入口 (router/enter.go):
```go
package router
type RouterGroup struct {
XxxRouter
YyyRouter
// 其他路由...
}
var RouterGroupApp = new(RouterGroup)
```
### Swagger注释规范:
- @Tags: 接口所属的分组
- @Summary: 接口功能简述
- @Security: 安全认证方式(如需认证则添加)
- @accept/@Produce: 请求/响应格式
- @Param: 请求参数,包括名称、来源、类型、是否必须、描述
- @Success: 成功响应,包括状态码、返回类型、描述
- @Router: 接口路径和HTTP方法
API函数的Swagger注释不仅用于生成API文档,也是前端开发的重要参考,请确保注释的完整性和准确性。
---
### **开发工作流**
1. **接收任务**: 我会向你下达一个具体的功能插件开发任务,例如:“请为项目创建一个‘商品管理 (Product)’插件”。
2. **【第一步】模型设计 (奠定基础)**:
- 你的**首要行动**是分析需求,设计并提供 `model` 和 `model/request` 下的所有 Go 结构体定义。这是后续所有开发的基础。
3. **【第二步】自下而上,分层实现**:
- 具体项目结构可以参考:server/plugin/announcement 这个插件,非常经典!
- 在模型确认后,你将按照 `Service -> API -> Router` 的顺序,逐层生成代码。
- 确保每一层的代码都完整、健壮,并严格遵守上述规范。
4. **【第三步】插件初始化与注册**:
- 在完成核心功能层的代码后,你将生成 `initialize/` 目录下的相关初始化文件(如 `db.go`, `router.go`)以及插件的主入口文件 `plugin.go`。
5. **【第四步】提供完整代码**:
- 你的最终回答应该是包含了该插件所有必需文件的、可直接复制使用的完整 Go 代码,并对每个文件的**相对路径**(例如 `server/plugin/product/api/product_api.go`)和用途进行清晰的说明。
---
## **前端开发规范**
### **角色与目标**
你是一名资深的 Vue.js 前端开发专家,**专精于 `gin-vue-admin` (GVA) 框架的前端架构与开发范式**。
你的核心任务是,根据需求开发**完整、生产级别的前端功能模块或插件**。你必须严格遵循 GVA 的前端架构、代码规范和核心设计模式,确保你生成的每一部分代码都能无缝集成到现有项目中。
### **核心开发指令:绝不可违背的原则**
#### 前端规则
在编写任何前端代码之前,你必须将以下 GVA 的核心设计原则作为最高行为准则:
1. **严格的模块化架构**:
- **职责单一**: 每个模块(API、组件、页面、状态)都有其唯一职责,**严禁跨模块直接调用**
- **依赖关系**: 依赖链条必须是单向的:`页面组件 -> API服务 -> 后端接口`
2. **统一的API调用模式**:
- 所有API调用**必须**通过 `src/api/` 目录下的专门文件进行封装
- **必须**使用项目统一的 `@/utils/request.js` 进行HTTP请求
- API函数**必须**包含完整的JSDoc注释,描述接口功能、参数和返回值
3. **组件化开发原则**:
- **每一个**可复用的UI元素都**必须**封装为组件
- 组件**必须**遵循单一职责原则,功能明确
- **必须**为组件添加完整的props定义和事件说明
4. **统一的状态管理**:
- 全局状态**必须**使用Pinia进行管理
- 状态模块**必须**按业务功能进行划分
- **严禁**在组件中直接修改全局状态,必须通过actions
### **各层级代码实现规范**
#### **1. API层 (`src/api/`)**
- **职责**: 封装所有后端API调用,提供统一的接口服务
- **结构**: 按业务模块创建API文件,如 `user.js`、`menu.js`
- **规范**:
```javascript
import service from '@/utils/request'
/**
* 获取用户列表
* @param {Object} data 查询参数
* @param {number} data.page 页码
* @param {number} data.pageSize 每页数量
* @returns {Promise} 用户列表数据
*/
export const getUserList = (data) => {
return service({
url: '/user/getUserList',
method: 'post',
data: data
})
}
```
#### **2. 组件层 (`src/components/`)**
- **职责**: 提供可复用的UI组件
- **结构**: 按功能分类组织,每个组件一个文件夹
- **规范**:
```vue
<template>
<div class="gva-table">
<!-- 组件内容 -->
</div>
</template>
<script setup>
/**
* 通用表格组件
* @component GvaTable
* @description 提供统一的表格展示功能
*/
// Props定义
const props = defineProps({
data: {
type: Array,
required: true,
default: () => []
},
loading: {
type: Boolean,
default: false
}
})
// 事件定义
const emit = defineEmits(['refresh', 'edit', 'delete'])
</script>
```
#### **3. 页面层 (`src/view/`)**
- **职责**: 实现具体的业务页面
- **结构**: 按业务模块组织,每个页面一个Vue文件
- **规范**:
- **必须**使用Composition API
- **必须**进行响应式数据管理
- **必须**处理加载状态和错误状态
- **必须**遵循Element Plus组件规范
- **必须**优先使用UnoCSS原子化类名进行样式设计
- **必须**优先el-drawer组件进行编辑,新增,步骤等操作
- **必须**使用el-drawer和el-dialog组件是后一定携带,destroy-on-close属性,确保组件销毁,避免内存泄漏和状态污染
#### **4. 状态管理 (`src/pinia/`)**
- **职责**: 管理全局状态和业务逻辑
- **结构**: 按业务模块创建store文件
- **规范**:
```javascript
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useStorage } from '@vueuse/core'
export const useUserStore = defineStore('user', () => {
// 状态定义 - 使用 ref() 创建响应式状态
const userInfo = ref({
uuid: '',
nickName: '',
headerImg: '',
authority: {}
})
const token = useStorage('token', '')
// 计算属性 - 使用 computed() 定义
const isLogin = computed(() => !!token.value)
// 方法定义 - 直接定义函数作为 actions
const setUserInfo = (val) => {
userInfo.value = val
}
const setToken = (val) => {
token.value = val
}
const login = async (loginForm) => {
// 登录逻辑
try {
const res = await loginApi(loginForm)
if (res.code === 0) {
setUserInfo(res.data.user)
setToken(res.data.token)
return true
}
return false
} catch (error) {
console.error('Login error:', error)
return false
}
}
const logout = async () => {
// 登出逻辑
token.value = ''
userInfo.value = {}
}
// 返回所有需要暴露的状态和方法
return {
userInfo,
token,
isLogin,
setUserInfo,
setToken,
login,
logout
}
})
```
#### **5. 路由管理 (`src/router/`)**
- **职责**: 管理页面路由和权限控制
- **规范**:
- **必须**配置路由元信息
- **必须**实现权限验证
- **必须**支持动态路由
### **前端插件开发规范**
#### **插件目录结构**
```
src/plugin/[插件名]/
├── api/ # 插件API接口
│ └── [模块].js
├── components/ # 插件组件(可选)
│ └── [组件名].vue
├── view/ # 插件页面
│ └── [页面名].vue
├── form/ # 插件表单(可选)
│ └── [表单名].vue
└── index.js # 插件入口文件(可选)
```
#### **插件开发原则**
1. **独立性**: 插件应该是自包含的,不依赖其他业务模块
2. **可配置性**: 插件应该支持配置化,便于定制
3. **可扩展性**: 插件应该预留扩展接口
4. **一致性**: 插件UI风格应与主系统保持一致
### **代码质量要求**
1. **命名规范**:
- 文件名:kebab-case(短横线命名)
- 组件名:PascalCase(大驼峰)
- 变量名:camelCase(小驼峰)
- 常量名:UPPER_SNAKE_CASE(大写下划线)
2. **注释规范**:
- **必须**为所有API函数添加JSDoc注释
- **必须**为复杂组件添加功能说明
- **必须**为关键业务逻辑添加行内注释
3. **样式规范**:
- **优先**使用UnoCSS原子化类名
- **必须**遵循Element Plus设计规范
- **禁止**使用内联样式
- **必须**使用CSS变量进行主题定制
4. **性能要求**:
- **必须**使用懒加载优化路由
- **必须**对大列表进行虚拟滚动优化
- **必须**合理使用缓存机制
- **必须**优化图片和资源加载
---
## **⚠️ 前端工具库使用规范(强制)**
> **核心原则:在开发任何前端功能时,必须优先检查并使用 `src/utils/` 目录下已封装好的工具函数,严禁重复造轮子。**
`src/utils/` 目录提供了项目级别的通用工具集,涵盖 HTTP 请求、日期处理、格式转换、字符串操作、图片处理等多个方面。以下是各工具文件的功能说明:
### **工具文件清单**
#### `request.js` — HTTP 请求封装(核心)
- 基于 Axios 封装的统一 HTTP 请求实例,内置全局 Loading 状态管理、JWT Token 自动注入、统一错误处理和响应拦截
- **所有 API 请求必须且只能通过此模块发送,禁止直接使用 axios**
- 用法:`import service from '@/utils/request'`
#### `date.js` — 日期格式化
- 扩展了 `Date.prototype.Format` 方法,支持自定义格式如 `yyyy-MM-dd hh:mm:ss`
- 导出 `formatTimeToStr(times, pattern)` 将时间戳或日期对象格式化为字符串
- **需要格式化日期时,优先使用此工具,禁止自行手写日期格式化逻辑**
- 用法:`import { formatTimeToStr } from '@/utils/date'`
#### `format.js` — 数据展示格式化(综合工具)
- `formatBoolean(bool)` — 将布尔值转为 "是"/"否" 中文展示
- `formatDate(time)` — 将时间转为 `yyyy-MM-dd hh:mm:ss` 格式字符串
- `filterDict(value, options)` — 在字典选项数组(支持多级树形)中根据 value 查找对应的 label
- `filterDataSource(dataSource, value)` — 在数据源(支持多级树形)中根据 value 查找 label,支持数组批量查找
- `getDictFunc(type)` — 异步获取指定类型的字典数据
- `ReturnArrImg(arr)` — 将图片路径(单个或数组)转为完整 URL,自动补全服务器前缀
- `onDownloadFile(url)` — 触发文件下载
- `setBodyPrimaryColor(primaryColor, darkMode)` — 动态设置主题色相关的 CSS 变量(支持亮/暗模式)
- `CreateUUID()` — 生成 UUID v4 字符串
- `getBaseUrl()` — 获取当前环境的 API BaseURL
- **以上所有格式化场景优先使用此文件中的工具函数**
- 用法:`import { formatBoolean, formatDate, filterDict, CreateUUID, ... } from '@/utils/format'`
#### `dictionary.js` — 字典数据获取
- `getDict(type, options)` — 异步获取字典数据,支持 `depth`(深度)和 `value`(指定节点)参数,内置 Pinia store 缓存,避免重复请求
- **凡是需要字典下拉数据、字典树形数据的场景,必须使用此工具**
- 用法:`import { getDict } from '@/utils/dictionary'`
#### `stringFun.js` — 字符串处理
- `toUpperCase(str)` — 首字母转大写
- `toLowerCase(str)` — 首字母转小写
- `toSQLLine(str)` — 驼峰命名转下划线(snake_case),如 `userName` → `user_name`
- `toHump(name)` — 下划线命名转驼峰,如 `user_name` → `userName`
- **进行命名格式转换时必须使用此工具,禁止使用正则手写**
- 用法:`import { toUpperCase, toSQLLine, toHump } from '@/utils/stringFun'`
#### `params.js` — 系统参数获取
- `getParams(key)` — 异步从 Pinia store 中获取系统参数,内置缓存
- **获取系统配置参数时,优先使用此工具**
- 用法:`import { getParams } from '@/utils/params'`
#### `bus.js` — 全局事件总线
- 基于 `mitt` 封装的全局事件总线实例 `emitter`,用于跨组件通信
- **跨层级组件通信优先使用此事件总线,避免滥用 Pinia**
- 用法:`import { emitter } from '@/utils/bus'`
#### `closeThisPage.js` — 关闭当前标签页
- `closeThisPage()` — 触发关闭当前多标签页的操作(通过事件总线发送 `closeThisPage` 事件)
- **在需要程序化关闭当前页面时,必须使用此工具**
- 用法:`import { closeThisPage } from '@/utils/closeThisPage'`
#### `downloadImg.js` — 图片下载
- `downloadImage(imgsrc, name)` — 通过 Canvas 将图片转为 base64 后触发下载,支持跨域
- **需要下载图片时,优先使用此工具**
- 用法:`import { downloadImage } from '@/utils/downloadImg'`
#### `image.js` — 图片压缩
- 导出 `ImageCompress` 类,支持图片等比压缩至指定最大宽高,并可限制文件大小
- **上传图片前需要做压缩处理时,使用此工具**
- 用法:`import ImageCompress from '@/utils/image'`
#### `event.js` — DOM 事件监听管理
- `addEventListen(target, event, handler, capture)` — 安全地添加 DOM 事件监听
- `removeEventListen(target, event, handler, capture)` — 安全地移除 DOM 事件监听
- **手动操作 DOM 事件时,使用此工具以确保安全性**
- 用法:`import { addEventListen, removeEventListen } from '@/utils/event'`
#### `env.js` — 环境判断
- `isDev` — 是否为开发环境(Boolean)
- `isProd` — 是否为生产环境(Boolean)
- **需要区分运行环境时,使用此工具,禁止直接读取 `import.meta.env`**
- 用法:`import { isDev, isProd } from '@/utils/env'`
#### `doc.js` — 外部文档跳转
- `toDoc(url)` — 在新标签页打开指定 URL
- 用法:`import { toDoc } from '@/utils/doc'`
#### `fmtRouterTitle.js` — 路由标题格式化
- `fmtTitle(title, route)` — 解析路由标题中的动态参数插值(如 `${id}` 替换为路由 params/query 值)
- 用法:`import { fmtTitle } from '@/utils/fmtRouterTitle'`
#### `page.js` — 页面标题生成
- `getPageTitle(pageTitle, route)` — 根据页面标题和路由生成完整的浏览器 Tab 标题(格式:`页面名 - 应用名`)
- 用法:`import getPageTitle from '@/utils/page'`
#### `asyncRouter.js` — 异步路由处理
- `asyncRouterHandle(asyncRouter)` — 将后端返回的路由配置(字符串 component 路径)动态转换为 Vue 组件的 import 函数,支持 `view/` 和 `plugin/` 目录
- **动态路由相关逻辑已由此工具处理,不需要也不应该手动实现**
- 用法:`import { asyncRouterHandle } from '@/utils/asyncRouter'`
#### `btnAuth.js` — 按钮权限
- `useBtnAuth()` — Composition API Hook,返回当前路由挂载的按钮权限对象(来自 `route.meta.btns`),用于控制操作按钮的显示
- **实现按钮级别权限控制时,必须使用此 Hook**
- 用法:`import { useBtnAuth } from '@/utils/btnAuth'`
### **使用强制要求**
| 场景 | 必须使用的工具 |
|------|----------------|
| 发送 HTTP 请求 | `@/utils/request` |
| 格式化日期时间 | `@/utils/date` 或 `@/utils/format` 中的 `formatDate` |
| 获取字典数据 | `@/utils/dictionary` 中的 `getDict` |
| 布尔值/字典值展示转换 | `@/utils/format` 中的 `formatBoolean` / `filterDict` |
| 生成 UUID | `@/utils/format` 中的 `CreateUUID` |
| 驼峰/下划线命名转换 | `@/utils/stringFun` |
| 获取系统参数 | `@/utils/params` 中的 `getParams` |
| 按钮权限判断 | `@/utils/btnAuth` 中的 `useBtnAuth` |
| 跨组件事件通信 | `@/utils/bus` 中的 `emitter` |
| 图片下载 | `@/utils/downloadImg` 中的 `downloadImage` |
| 图片上传压缩 | `@/utils/image` 中的 `ImageCompress` |
| 关闭当前 Tab 页 | `@/utils/closeThisPage` 中的 `closeThisPage` |
---
## **前后端协作规范**
### **接口协作规范**
1. **接口文档**:
- 后端**必须**提供完整的Swagger API文档
- 前端**必须**基于Swagger文档进行接口调用
- 接口变更**必须**提前通知并更新文档
2. **数据格式**:
- **统一**使用JSON格式进行数据交换
- **统一**响应格式:`{code, data, msg}`
- **统一**分页格式:`{page, pageSize, total, list}`
- **统一**时间格式:ISO 8601标准
- **⚠️ 数据类型一致性**:
- 前后端对于同一字段**必须**使用相同的数据类型
- 后端Go结构体中的字段类型必须与前端JavaScript/TypeScript中的类型定义保持一致
- 特别注意:状态字段、ID字段、枚举值、时间字段等容易出现类型不匹配的字段
- 示例:后端数值类型字段对应前端 `number` 类型,字符串类型对应 `string` 类型,布尔类型对应 `boolean` 类型
- **指针类型处理**:后端Go中的指针类型在JSON序列化时会自动处理nil值,前端接收到的是对应的基础类型或null值
3. **错误处理**:
- 后端**必须**返回标准化的错误码和错误信息
- 前端**必须**统一处理HTTP状态码和业务错误码
- **必须**提供用户友好的错误提示
### **开发流程规范**
1. **需求分析阶段**:
- 确定功能需求和接口设计
- 定义数据模型和业务流程
- 制定前后端开发计划
2. **开发阶段**:
- 后端优先开发API接口
- 前端基于Mock数据进行并行开发
- 定期进行接口联调测试
3. **测试阶段**:
- 单元测试:前后端各自负责
- 集成测试:前后端协作完成
- 用户验收测试:产品团队主导
### **版本管理规范**
1. **分支策略**:
- `main`:生产环境分支
- `develop`:开发环境分支
- `feature/*`:功能开发分支
- `hotfix/*`:紧急修复分支
2. **提交规范**:
- 使用语义化提交信息
- 格式:`type(scope): description`
- 类型:feat, fix, docs, style, refactor, test, chore
---
## **插件开发完整规范**
### **后端插件结构**
```
server/plugin/[插件名]/
├── api/ # API控制器
│ ├── enter.go # API组入口
│ └── [模块].go # 具体API实现
├── config/ # 插件配置
│ └── config.go
├── initialize/ # 初始化模块
│ ├── api.go # API注册
│ ├── gorm.go # 数据库初始化
│ ├── menu.go # 菜单初始化
│ ├── router.go # 路由初始化
│ └── viper.go # 配置初始化
├── model/ # 数据模型
│ ├── [模型].go # 数据库模型
│ └── request/ # 请求模型
├── router/ # 路由定义
│ ├── enter.go # 路由组入口
│ └── [模块].go # 具体路由
├── service/ # 业务服务
│ ├── enter.go # 服务组入口
│ └── [模块].go # 具体服务
└── plugin.go # 插件入口
```
### **前端插件结构**
```
web/src/plugin/[插件名]/
├── api/ # API接口
│ └── [模块].js
├── components/ # 插件组件
│ └── [组件].vue
├── view/ # 插件页面
│ └── [页面].vue
├── form/ # 表单组件
│ └── [表单].vue
└── config.js # 插件配置
```
### **插件开发工作流**
1. **【第一步】需求分析**:
- 明确插件功能和业务需求
- 设计数据模型和接口规范
- 规划前端页面和交互流程
2. **【第二步】后端开发**:
- 创建数据模型和请求模型
- 实现服务层业务逻辑
- 开发API控制器和路由
- 编写初始化和配置代码
3. **【第三步】前端开发**:
- 创建API接口封装
- 开发页面组件和表单
- 实现业务逻辑和状态管理
- 集成到主系统菜单
4. **【第四步】测试集成**:
- 单元测试和集成测试
- 前后端联调测试
- 用户体验测试
- 性能和安全测试
### **插件质量标准**
1. **功能完整性**: 插件功能完整,满足业务需求
2. **代码质量**: 代码规范,注释完整,易于维护
3. **数据类型一致性**: 前后端数据模型字段类型保持严格一致,避免类型转换错误
4. **性能表现**: 响应速度快,资源占用合理
5. **用户体验**: 界面友好,操作流畅,错误处理完善
6. **兼容性**: 与主系统兼容,不影响其他功能
7. **安全性**: 数据安全,权限控制,防止安全漏洞
---
### **建议和方案**
基于以上规范,建议AI在开发gin-vue-admin项目时:
1. **严格遵循分层架构**:确保前后端代码都按照规定的层次结构组织
2. **保持代码一致性**:使用统一的命名规范、注释格式和代码风格
3. **注重文档完整性**:确保API文档、代码注释和使用说明的完整性
4. **优化用户体验**:关注页面加载速度、交互流畅性和错误处理
5. **考虑扩展性**:设计时预留扩展接口,便于后续功能增强
6. **重视安全性**:实现完善的权限控制和数据验证机制
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at 303176530@qq.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: CONTRIBUTING.md
================================================
### Contributing Guide
#### 1 Issue Guidelines
- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help.
- Before submitting an issue, please check if similar problems have already been issued.
#### 2 Pull Request Guidelines
- Fork this repository to your own account. Do not create branches here.
- Commit info should be formatted as `[File Name]: Info about commit.` (e.g. `README.md: Fix xxx bug`)
- <font color=red>Make sure PRs are created to `develop` branch instead of `master` branch.</font>
- If your PR fixes a bug, please provide a description about the related bug.
- Merging a PR takes two maintainers: one approves the changes after reviewing, and then the other reviews and merges.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 北京翻转极光科技有限责任公司
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
SHELL = /bin/bash
#SCRIPT_DIR = $(shell pwd)/etc/script
#请选择golang版本
BUILD_IMAGE_SERVER = golang:1.22
#请选择node版本
BUILD_IMAGE_WEB = node:20
#项目名称
PROJECT_NAME = github.com/flipped-aurora/gin-vue-admin/server
#配置文件目录
CONFIG_FILE = config.yaml
#镜像仓库命名空间
IMAGE_NAME = gva
#镜像地址
REPOSITORY = registry.cn-hangzhou.aliyuncs.com/${IMAGE_NAME}
#镜像版本
TAGS_OPT ?= latest
PLUGIN ?= email
#容器环境前后端共同打包
build: build-web build-server
docker run --name build-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_SERVER} make build-local
#容器环境打包前端
build-web:
docker run --name build-web-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_WEB} make build-web-local
#容器环境打包后端
build-server:
docker run --name build-server-local --rm -v $(shell pwd):/go/src/${PROJECT_NAME} -w /go/src/${PROJECT_NAME} ${BUILD_IMAGE_SERVER} make build-server-local
#构建web镜像
build-image-web:
@cd web/ && docker build -t ${REPOSITORY}/web:${TAGS_OPT} .
#构建server镜像
build-image-server:
@cd server/ && docker build -t ${REPOSITORY}/server:${TAGS_OPT} .
#本地环境打包前后端
build-local:
if [ -d "build" ];then rm -rf build; else echo "OK!"; fi \
&& if [ -f "/.dockerenv" ];then echo "OK!"; else make build-web-local && make build-server-local; fi \
&& mkdir build && cp -r web/dist build/ && cp server/server build/ && cp -r server/resource build/resource
#本地环境打包前端
build-web-local:
@cd web/ && if [ -d "dist" ];then rm -rf dist; else echo "OK!"; fi \
&& yarn config set registry http://mirrors.cloud.tencent.com/npm/ && yarn install && yarn build
#本地环境打包后端
build-server-local:
@cd server/ && if [ -f "server" ];then rm -rf server; else echo "OK!"; fi \
&& go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w CGO_ENABLED=0 && go env && go mod tidy \
&& go build -ldflags "-B 0x$(shell head -c20 /dev/urandom|od -An -tx1|tr -d ' \n') -X main.Version=${TAGS_OPT}" -v
#打包前后端二合一镜像
image: build
docker build -t ${REPOSITORY}/gin-vue-admin:${TAGS_OPT} -f deploy/docker/Dockerfile .
#尝鲜版
images: build build-image-web build-image-server
docker build -t ${REPOSITORY}/all:${TAGS_OPT} -f deploy/docker/Dockerfile .
#swagger 文档生成
doc:
@cd server && swag init
#插件快捷打包: make plugin PLUGIN="这里是插件文件夹名称,默认为email"
plugin:
if [ -d ".plugin" ];then rm -rf .plugin ; else echo "OK!"; fi && mkdir -p .plugin/${PLUGIN}/{server/plugin,web/plugin} \
&& if [ -d "server/plugin/${PLUGIN}" ];then cp -r server/plugin/${PLUGIN} .plugin/${PLUGIN}/server/plugin/ ; else echo "OK!"; fi \
&& if [ -d "web/src/plugin/${PLUGIN}" ];then cp -r web/src/plugin/${PLUGIN} .plugin/${PLUGIN}/web/plugin/ ; else echo "OK!"; fi \
&& cd .plugin && zip -r ${PLUGIN}.zip ${PLUGIN} && mv ${PLUGIN}.zip ../ && cd ..
================================================
FILE: README-en.md
================================================
<div align=center>
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width="300" height="300" />
</div>
<div align=center>
<img src="https://img.shields.io/badge/golang-1.18-blue"/>
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
</div>
English | [简体中文](./README.md)
[gitee](https://gitee.com/pixelmax/gin-vue-admin): https://gitee.com/pixelmax/gin-vue-admin
[github](https://github.com/flipped-aurora/gin-vue-admin): https://github.com/flipped-aurora/gin-vue-admin
# Project Guidelines
[Online Documentation](https://www.gin-vue-admin.com/) : https://www.gin-vue-admin.com/
[From the environment to the deployment of teaching videos](https://www.bilibili.com/video/BV1fV411y7dT)
[Development Steps](https://www.gin-vue-admin.com/guide/start-quickly/env.html) (Contributor: <a href="https://github.com/LLemonGreen">LLemonGreen</a> And <a href="https://github.com/fkk0509">Fann</a>)
## 1. Basic Introduction
### 1.1 Project Introduction
> Gin-vue-admin is a backstage management system based on [vue](https://vuejs.org) and [gin](https://gin-gonic.com), which separates the front and rear of the full stack. It integrates jwt authentication, dynamic routing, dynamic menu, casbin authentication, form generator, code generator and other functions. It provides a variety of sample files, allowing you to focus more time on business development.
[Online Demo](http://demo.gin-vue-admin.com): http://demo.gin-vue-admin.com
username:admin
password:123456
### 1.2 Contributing Guide
Hi! Thank you for choosing gin-vue-admin.
Gin-vue-admin is a full-stack (frontend and backend separation) framework for developers, designers and product managers.
We are excited that you are interested in contributing to gin-vue-admin. Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.
#### 1.2.1 Issue Guidelines
- Issues are exclusively for bug reports, feature requests and design-related topics. Other questions may be closed directly. If any questions come up when you are using Element, please hit [Gitter](https://gitter.im/element-en/Lobby) for help.
- Before submitting an issue, please check if similar problems have already been issued.
#### 1.2.2 Pull Request Guidelines
- Fork this repository to your own account. Do not create branches here.
- Commit info should be formatted as `[File Name]: Info about commit.` (e.g. `README.md: Fix xxx bug`)
- <font color=red>Make sure PRs are created to `develop` branch instead of `master` branch.</font>
- If your PR fixes a bug, please provide a description about the related bug.
- Merging a PR takes two maintainers: one approves the changes after reviewing, and then the other reviews and merges.
### 1.3 Version list
- master: 2.0 code, for prod
- develop: 2.0 dev code, for test
- [gin-vue-admin_v2_dev](https://github.com/flipped-aurora/gin-vue-admin/tree/gin-vue-admin_v2_dev) (v2.0 [GormV1](https://v1.gorm.io) Stable branch)
- [gva_gormv2_dev](https://github.com/flipped-aurora/gin-vue-admin/tree/gva_gormv2_dev) (v2.0 [GormV2](https://v2.gorm.io) Development branch)
## 2. Getting started
```
- node version > v8.6.0
- golang version >= v1.14
- IDE recommendation: Goland
- initialization project: different versions of the database are not initialized. See synonyms at initialization https://www.gin-vue-admin.com/docs/first
- Replace the Qiniuyun public key, private key, warehouse name and default url address in the project to avoid data confusion in the test file.
```
### 2.1 server project
use `Goland` And other editing tools,open server catalogue,You can't open it. `gin-vue-admin` root directory
```bash
# clone the project
git clone https://github.com/flipped-aurora/gin-vue-admin.git
# open server catalogue
cd server
# use go mod And install the go dependency package
go generate
# Compile
go build -o server main.go (windows the compile command is go build -o server.exe main.go )
# Run binary
./server (windows The run command is server.exe)
```
### 2.1 web project
```bash
# enter the project directory
cd web
# install dependency
npm install
# develop
npm run serve
```
### 2.2 Server
```bash
# using go.mod
# install go modules
go list (go mod tidy)
# build the server
go build
```
### 2.3 API docs auto-generation using swagger
#### 2.3.1 install swagger
##### (1) Using VPN or outside mainland China
````
go get -u github.com/swaggo/swag/cmd/swag
````
##### (2) In mainland China
In mainland China, access to go.org/x is prohibited,we recommend [goproxy.io](https://goproxy.io/zh/) or [goproxy.cn](https://goproxy.cn)
````bash
# If you are using a version of Go 1.13 - 1.15 Need to set up manually GO111MODULE=on, The opening mode is as follows, If your Go version is 1.16 ~ Latest edition You can ignore the following step one
# Step one、Enable Go Modules Function
go env -w GO111MODULE=on
# Step two、Configuration GOPROXY Environment variable
go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct
# If you dislike trouble,You can use the go generate Automatically execute code before compilation, But this can't be used command line terminal of `Goland` or `Vscode`
cd server
go generate -run "go env -w .*?"
# Use the following command to download swag
go get -u github.com/swaggo/swag/cmd/swag
````
#### 2.3.2 API docs generation
````
cd server
swag init
````
> After executing the above command,server directory will appear in the docs folder `docs.go`, `swagger.json`, `swagger.yaml` Three file updates,After starting the go service, type in the browser [http://localhost:8888/swagger/index.html](http://localhost:8888/swagger/index.html) You can view swagger document
## 3. Technical selection
- Frontend: using [Element](https://github.com/ElemeFE/element) based on [Vue](https://vuejs.org),to code the page.
- Backend: using [Gin](https://gin-gonic.com/) to quickly build basic RESTful API. [Gin](https://gin-gonic.com/)is a web framework written in Go (Golang).
- DB: `MySql`(5.6.44),using [gorm](http://gorm.io)` to implement data manipulation, added support for SQLite databases.
- Cache: using `Redis` to implement the recording of the JWT token of the currently active user and implement the multi-login restriction.
- API: using Swagger to auto generate APIs docs。
- Config: using [fsnotify](https://github.com/fsnotify/fsnotify) and [viper](https://github.com/spf13/viper) to implement `yaml` config file。
- Log: using [zap](https://github.com/uber-go/zap) record logs。
## 4. Project Architecture
### 4.1 Architecture Diagram

### 4.2 Front-end Detailed Design Diagram (Contributor: <a href="https://github.com/baobeisuper">baobeisuper</a>)

### 4.3 Project Layout
```
├── server
├── api (api entrance)
│ └── v1 (v1 version interface)
├── config (configuration package)
├── core (core document)
├── docs (swagger document directory)
├── global (global object)
├── initialize (initialization)
│ └── internal (initialize internal function)
├── middleware (middleware layer)
├── model (model layer)
│ ├── request (input parameter structure)
│ └── response (out-of-parameter structure)
├── packfile (static file packaging)
├── resource (static resource folder)
│ ├── excel (excel import and export default path)
│ ├── page (form generator)
│ └── template (template)
├── router (routing layer)
├── service (service layer)
├── source (source layer)
└── utils (tool kit)
├── timer (timer interface encapsulation)
└── upload (oss interface encapsulation)
└─web (frontend)
├─public (deploy templates)
└─src (source code)
├─api (frontend APIs)
├─assets (static files)
├─components(components)
├─router (frontend routers)
├─store (vuex state management)
├─style (common styles)
├─utils (frontend common utilitie)
└─view (pages)
```
## 5. Features
- Authority management: Authority management based on `jwt` and `casbin`.
- File upload and download: implement file upload operations based on `Qiniuyun', `Aliyun 'and `Tencent Cloud` (please develop your own application for each platform corresponding to `token` or `key` ).
- Pagination Encapsulation:The frontend uses `mixins` to encapsulate paging, and the paging method can call `mixins` .
- User management: The system administrator assigns user roles and role permissions.
- Role management: Create the main object of permission control, and then assign different API permissions and menu permissions to the role.
- Menu management: User dynamic menu configuration implementation, assigning different menus to different roles.
- API management: Different users can call different API permissions.
- Configuration management: the configuration file can be modified in the foreground (this feature is not available in the online experience site).
- Conditional search: Add an example of conditional search.
- Restful example: You can see sample APIs in user management module.
- Front-end file reference: [web/src/view/superAdmin/api/api.vue](https://github.com/flipped-aurora/gin-vue-admin/blob/master/web/src/view/superAdmin/api/api.vue).
- Stage reference: [server/router/sys_api.go](https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/router/sys_api.go).
- Multi-login restriction: Change `user-multipoint` to true in `system` in `config.yaml` (You need to configure redis and redis parameters yourself. During the test period, please report in time if there is a bug).
- Upload file by chunk:Provides examples of file upload and large file upload by chunk.
- Form Builder:With the help of [@form-generator](https://github.com/JakHuang/form-generator).
- Code generator: Providing backend with basic logic and simple curd code generator.
## 6. Knowledge base
### 6.1 Team blog
> https://www.yuque.com/flipped-aurora
>
>There are video courses about frontend framework in our blo. If you think the project is helpful to you, you can add my personal WeChat:shouzi_1994,your comments is welcomed。
### 6.2 Video courses
(1) Development environment course
> Bilibili:https://www.bilibili.com/video/BV1Fg4y187Bw/
(2) Template course
> Bilibili:https://www.bilibili.com/video/BV16K4y1r7BD/
(3) 2.0 version introduction and development experience
> Bilibili:https://www.bilibili.com/video/BV1aV411d7Gm#reply2831798461
(4) Golang basic course
> https://space.bilibili.com/322210472/channel/detail?cid=108884
(5) gin frame basic teaching
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
(6) gin-vue-admin version update introduction video
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
## 7.Contacts
### 7.1 Groups
#### QQ group: 622360840
| QQ group |d
| :---: |
| <img src="http://qmplusimg.henrongyi.top/qq.jpg" width="180"/> |
#### Wechat group: comment "加入gin-vue-admin交流群"
| Wechat |
| :---: |
| <img width="150" src="http://qmplusimg.henrongyi.top/qrjjz.png">
#### [About Us](https://www.gin-vue-admin.com/about/join.html)
## 8. Contributors
Thank you for considering your contribution to gin-vue-admin!
<a href="https://openomy.app/github/flipped-aurora/gin-vue-admin" target="_blank" style="display: block; width: 100%;" align="center">
<img src="https://openomy.app/svg?repo=flipped-aurora/gin-vue-admin&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
</a>
<a href="https://github.com/flipped-aurora/gin-vue-admin/graphs/contributors">
<img src="https://contrib.rocks/image?repo=flipped-aurora/gin-vue-admin" />
</a>
## 9. Donate
If you find this project useful, you can buy author a glass of juice :tropical_drink: [here](https://www.gin-vue-admin.com/coffee/index.html)
## 10. Commercial considerations
If you use this project for commercial purposes, please comply with the Apache2.0 agreement and retain the author's technical support statement.
================================================
FILE: README.md
================================================
<div align=center>
<img src="http://qmplusimg.henrongyi.top/gvalogo.jpg" width="300" height="300" />
</div>
<div align=center>
<img src="https://img.shields.io/badge/golang-1.20-blue"/>
<img src="https://img.shields.io/badge/gin-1.9.1-lightBlue"/>
<img src="https://img.shields.io/badge/vue-3.3.4-brightgreen"/>
<img src="https://img.shields.io/badge/element--plus-2.3.8-green"/>
<img src="https://img.shields.io/badge/gorm-1.25.2-red"/>
<img src="https://gitcode.com/flipped-aurora/gin-vue-admin/star/badge.svg"/>
</div>
<div align=center>
<a href="https://trendshift.io/repositories/3250" target="_blank"><img src="https://trendshift.io/api/badge/repositories/3250" alt="Calcium-Ion%2Fnew-api | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
[English](./README-en.md) | 简体中文
## 支持claw生态
[🦞GvaClaw](https://plugin.gin-vue-admin.com/details/159)
## ✨一分钟生成前后端基础代码
<table>
<tr>
<td width="250">
<p>⭐️ <a href="https://www.bilibili.com/video/BV1B3htzqEf1/?spm_id_from=333.1387.homepage.video_card.click" target="__blank"> 高度适配AI编辑器的MCP </a></p>
<p>📄 创建基础模板</p>
<p>🤖 AI生成结构</p>
<p>⏰ 生成代码</p>
<p>🏷️ 分配权限</p>
<p>🎉 基础CURD生成完成</p>
</td>
<td>
<video src="https://private-user-images.githubusercontent.com/165128580/384700666-4d039215-af29-4f86-bb4f-60dbab38f58e.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzEyNTIxNDYsIm5iZiI6MTczMTI1MTg0NiwicGF0aCI6Ii8xNjUxMjg1ODAvMzg0NzAwNjY2LTRkMDM5MjE1LWFmMjktNGY4Ni1iYjRmLTYwZGJhYjM4ZjU4ZS5tcDQ_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMTEwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTExMFQxNTE3MjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00NjJkMDcwZjJkMjAyMmU1N2I2MzQxY2RhODFlNzgzNGRiMDFhMmY2NTYyM2ZmODdhNDVmMWE1NzlhMDdlOTI5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ZJbswpLzF2RHjemcGirKOP0L1fvpl3FUqIiQ_-yjeUo" data-canonical-src="https://private-user-images.githubusercontent.com/165128580/384700666-4d039215-af29-4f86-bb4f-60dbab38f58e.mp4?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzEyNTIxNDYsIm5iZiI6MTczMTI1MTg0NiwicGF0aCI6Ii8xNjUxMjg1ODAvMzg0NzAwNjY2LTRkMDM5MjE1LWFmMjktNGY4Ni1iYjRmLTYwZGJhYjM4ZjU4ZS5tcDQ_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQxMTEwJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MTExMFQxNTE3MjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00NjJkMDcwZjJkMjAyMmU1N2I2MzQxY2RhODFlNzgzNGRiMDFhMmY2NTYyM2ZmODdhNDVmMWE1NzlhMDdlOTI5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCJ9.ZJbswpLzF2RHjemcGirKOP0L1fvpl3FUqIiQ_-yjeUo" controls="controls" muted="muted" class="d-block rounded-bottom-2 border-top width-fit" style="max-height:640px; min-height: 200px">
</video>
</td>
</tr>
</table>
# 项目文档
[在线文档](https://www.gin-vue-admin.com) : https://www.gin-vue-admin.com
[初始化](https://www.gin-vue-admin.com/guide/start-quickly/initialization.html)
[从环境到部署教学视频](https://www.bilibili.com/video/BV1Rg411u7xH)
[开发教学](https://www.gin-vue-admin.com/guide/start-quickly/env.html) (贡献者: <a href="https://github.com/LLemonGreen">LLemonGreen</a> And <a href="https://github.com/fkk0509">Fann</a>)
[交流社区](https://support.qq.com/products/371961)
[插件市场](https://plugin.gin-vue-admin.com/)
[软件著作权证书](https://www.gin-vue-admin.com/copyright.pdf)
# 重要提示
1.本项目从起步到开发到部署均有文档和详细视频教程
2.本项目需要您有一定的golang和vue基础
3.您完全可以通过我们的教程和文档完成一切操作,因此我们不再提供免费的技术服务,如需服务请进行[付费支持](https://www.gin-vue-admin.com/coffee/payment.html)
4.如果您将此项目用于商业用途,请遵守Apache2.0协议并保留作者技术支持声明。您需保留如下版权声明信息,以及日志和代码中所包含的版权声明信息。所需保留信息均为文案性质,不会影响任何业务内容,如决定商用【产生收益的商业行为均在商用行列】或者必须剔除请[购买授权](https://plugin.gin-vue-admin.com/licenseindex.html)
\
<img src="https://qmplusimg.henrongyi.top/openSource/login.jpg" width="1000">
<img src="https://qmplusimg.henrongyi.top/openSource/dashboard.jpg" width="1000">
## 1. 基本介绍
### 1.1 项目介绍
> Gin-vue-admin是一个基于 [vue](https://vuejs.org) 和 [gin](https://gin-gonic.com) 开发的全栈前后端分离的开发基础平台,集成jwt鉴权,动态路由,动态菜单,casbin鉴权,表单生成器,代码生成器等功能,提供多种示例文件,让您把更多时间专注在业务开发上。
[在线预览](http://demo.gin-vue-admin.com): http://demo.gin-vue-admin.com
测试用户名:admin
测试密码:123456
### 1.2 贡献指南
Hi! 首先感谢你使用 gin-vue-admin。
Gin-vue-admin 是一套为快速研发准备的一整套前后端分离架构式的开源框架,旨在快速搭建中小型项目。
Gin-vue-admin 的成长离不开大家的支持,如果你愿意为 gin-vue-admin 贡献代码或提供建议,请阅读以下内容。
#### 1.2.1 Issue 规范
- issue 仅用于提交 Bug 或 Feature 以及设计相关的内容,其它内容可能会被直接关闭。
- 在提交 issue 之前,请搜索相关内容是否已被提出。
#### 1.2.2 Pull Request 规范
- 请先 fork 一份到自己的项目下,不要直接在仓库下建分支。
- commit 信息要以`[文件名]: 描述信息` 的形式填写,例如 `README.md: fix xxx bug`。
- 如果是修复 bug,请在 PR 中给出描述信息。
- 合并代码需要两名维护人员参与:一人进行 review 后 approve,另一人再次 review,通过后即可合并。
## 2. 使用说明
```
- node版本 > v18.16.0
- golang版本 >= v1.22
- IDE推荐:Goland
```
### 2.1 server项目
使用 `Goland` 等编辑工具,打开server目录,不可以打开 gin-vue-admin 根目录
```bash
# 克隆项目
git clone https://github.com/flipped-aurora/gin-vue-admin.git
# 进入server文件夹
cd server
# 使用 go mod 并安装go依赖包
go generate
# 运行
go run .
```
### 2.2 web项目
```bash
# 进入web文件夹
cd web
# 安装依赖
npm install
# 启动web项目
npm run serve
```
### 2.3 swagger自动化API文档
#### 2.3.1 安装 swagger
``` shell
go install github.com/swaggo/swag/cmd/swag@latest
```
#### 2.3.2 生成API文档
```` shell
cd server
swag init
````
> 执行上面的命令后,server目录下会出现docs文件夹里的 `docs.go`, `swagger.json`, `swagger.yaml` 三个文件更新,启动go服务之后, 在浏览器输入 [http://localhost:8888/swagger/index.html](http://localhost:8888/swagger/index.html) 即可查看swagger文档
### 2.4 VSCode工作区
#### 2.4.1 开发
使用`VSCode`打开根目录下的工作区文件`gin-vue-admin.code-workspace`,在边栏可以看到三个虚拟目录:`backend`、`frontend`、`root`。
#### 2.4.2 运行/调试
在运行和调试中也可以看到三个task:`Backend`、`Frontend`、`Both (Backend & Frontend)`。运行`Both (Backend & Frontend)`可以同时启动前后端项目。
#### 2.4.3 settings
在工作区配置文件中有`go.toolsEnvVars`字段,是用于`VSCode`自身的go工具环境变量。此外在多go版本的系统中,可以通过`gopath`、`go.goroot`指定运行版本。
```json
"go.gopath": null,
"go.goroot": null,
```
## 3. 技术选型
- 前端:用基于 [Vue](https://vuejs.org) 的 [Element](https://github.com/ElemeFE/element) 构建基础页面。
- 后端:用 [Gin](https://gin-gonic.com/) 快速搭建基础restful风格API,[Gin](https://gin-gonic.com/) 是一个go语言编写的Web框架。
- 数据库:采用`MySql` > (5.7) 版本 数据库引擎 InnoDB,使用 [gorm](http://gorm.cn) 实现对数据库的基本操作。
- 缓存:使用`Redis`实现记录当前活跃用户的`jwt`令牌并实现多点登录限制。
- API文档:使用`Swagger`构建自动化文档。
- 配置文件:使用 [fsnotify](https://github.com/fsnotify/fsnotify) 和 [viper](https://github.com/spf13/viper) 实现`yaml`格式的配置文件。
- 日志:使用 [zap](https://github.com/uber-go/zap) 实现日志记录。
## 4. 项目架构
### 4.1 系统架构图

### 4.2 前端详细设计图 (提供者:<a href="https://github.com/baobeisuper">baobeisuper</a>)

### 4.3 目录结构
```
├── server
├── api (api层)
│ └── v1 (v1版本接口)
├── config (配置包)
├── core (核心文件)
├── docs (swagger文档目录)
├── global (全局对象)
├── initialize (初始化)
│ └── internal (初始化内部函数)
├── middleware (中间件层)
├── model (模型层)
│ ├── request (入参结构体)
│ └── response (出参结构体)
├── packfile (静态文件打包)
├── resource (静态资源文件夹)
│ ├── excel (excel导入导出默认路径)
│ ├── page (表单生成器)
│ └── template (模板)
├── router (路由层)
├── service (service层)
├── source (source层)
└── utils (工具包)
├── timer (定时器接口封装)
└── upload (oss接口封装)
web
├── babel.config.js
├── Dockerfile
├── favicon.ico
├── index.html -- 主页面
├── limit.js -- 助手代码
├── package.json -- 包管理器代码
├── src -- 源代码
│ ├── api -- api 组
│ ├── App.vue -- 主页面
│ ├── assets -- 静态资源
│ ├── components -- 全局组件
│ ├── core -- gva 组件包
│ │ ├── config.js -- gva网站配置文件
│ │ ├── gin-vue-admin.js -- 注册欢迎文件
│ │ └── global.js -- 统一导入文件
│ ├── directive -- v-auth 注册文件
│ ├── main.js -- 主文件
│ ├── permission.js -- 路由中间件
│ ├── pinia -- pinia 状态管理器,取代vuex
│ │ ├── index.js -- 入口文件
│ │ └── modules -- modules
│ │ ├── dictionary.js
│ │ ├── router.js
│ │ └── user.js
│ ├── router -- 路由声明文件
│ │ └── index.js
│ ├── style -- 全局样式
│ │ ├── base.scss
│ │ ├── basics.scss
│ │ ├── element_visiable.scss -- 此处可以全局覆盖 element-plus 样式
│ │ ├── iconfont.css -- 顶部几个icon的样式文件
│ │ ├── main.scss
│ │ ├── mobile.scss
│ │ └── newLogin.scss
│ ├── utils -- 方法包库
│ │ ├── asyncRouter.js -- 动态路由相关
│ │ ├── btnAuth.js -- 动态权限按钮相关
│ │ ├── bus.js -- 全局mitt声明文件
│ │ ├── date.js -- 日期相关
│ │ ├── dictionary.js -- 获取字典方法
│ │ ├── downloadImg.js -- 下载图片方法
│ │ ├── format.js -- 格式整理相关
│ │ ├── image.js -- 图片相关方法
│ │ ├── page.js -- 设置页面标题
│ │ ├── request.js -- 请求
│ │ └── stringFun.js -- 字符串文件
| ├── view -- 主要view代码
| | ├── about -- 关于我们
| | ├── dashboard -- 面板
| | ├── error -- 错误
| | ├── example --上传案例
| | ├── iconList -- icon列表
| | ├── init -- 初始化数据
| | | ├── index -- 新版本
| | | ├── init -- 旧版本
| | ├── layout -- layout约束页面
| | | ├── aside
| | | ├── bottomInfo -- bottomInfo
| | | ├── screenfull -- 全屏设置
| | | ├── setting -- 系统设置
| | | └── index.vue -- base 约束
| | ├── login --登录
| | ├── person --个人中心
| | ├── superAdmin -- 超级管理员操作
| | ├── system -- 系统检测页面
| | ├── systemTools -- 系统配置相关页面
| | └── routerHolder.vue -- page 入口页面
├── vite.config.js -- vite 配置文件
└── yarn.lock
```
## 5. 主要功能
- 权限管理:基于`jwt`和`casbin`实现的权限管理。
- 文件上传下载:实现基于`七牛云`, `阿里云`, `腾讯云` 的文件上传操作(请开发自己去各个平台的申请对应 `token` 或者对应`key`)。
- 分页封装:前端使用 `mixins` 封装分页,分页方法调用 `mixins` 即可。
- 用户管理:系统管理员分配用户角色和角色权限。
- 角色管理:创建权限控制的主要对象,可以给角色分配不同api权限和菜单权限。
- 菜单管理:实现用户动态菜单配置,实现不同角色不同菜单。
- api管理:不同用户可调用的api接口的权限不同。
- 配置管理:配置文件可前台修改(在线体验站点不开放此功能)。
- 条件搜索:增加条件搜索示例。
- restful示例:可以参考用户管理模块中的示例API。
- 前端文件参考: [web/src/view/superAdmin/api/api.vue](https://github.com/flipped-aurora/gin-vue-admin/blob/master/web/src/view/superAdmin/api/api.vue)
- 后台文件参考: [server/router/sys_api.go](https://github.com/flipped-aurora/gin-vue-admin/blob/master/server/router/sys_api.go)
- 多点登录限制:需要在`config.yaml`中把`system`中的`use-multipoint`修改为true(需要自行配置Redis和Config中的Redis参数,测试阶段,有bug请及时反馈)。
- 分片上传:提供文件分片上传和大文件分片上传功能示例。
- 表单生成器:表单生成器借助 [@Variant Form](https://github.com/vform666/variant-form) 。
- 代码生成器:后台基础逻辑以及简单curd的代码生成器。
## 6. 知识库
## 6.1 团队博客
> https://www.yuque.com/flipped-aurora
>
>内有前端框架教学视频。如果觉得项目对您有所帮助可以添加我的个人微信:shouzi_1994,欢迎您提出宝贵的需求。
## 6.2 教学视频
(1)手把手教学视频
> https://www.bilibili.com/video/BV1Rg411u7xH/
(2)后端目录结构调整介绍以及使用方法
> https://www.bilibili.com/video/BV1x44y117TT/
(3)golang基础教学视频
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=108884
(4)gin框架基础教学
> bilibili:https://space.bilibili.com/322210472/channel/detail?cid=126418&ctype=0
(5)gin-vue-admin 版本更新介绍视频
> bilibili:https://www.bilibili.com/video/BV1kv4y1g7nT
## 7. 联系方式
### 7.1 技术群
### QQ交流群:971857775
### 微信交流群
| 微信 |
| :---: |
| <img width="150" src="http://qmplusimg.henrongyi.top/qrjjz.png">
防止广告进群,添加微信,输入以下代码执行结果(请勿转码为string)
```
str := "5Yqg5YWlR1ZB5Lqk5rWB576k"
decodeBytes, err := base64.StdEncoding.DecodeString(str)
fmt.Println(decodeBytes, err)
```
### [关于我们](https://www.gin-vue-admin.com/about/join.html)
## 8. 贡献者
感谢您对gin-vue-admin的贡献!
<a href="https://openomy.app/github/flipped-aurora/gin-vue-admin" target="_blank" style="display: block; width: 100%;" align="center">
<img src="https://openomy.app/svg?repo=flipped-aurora/gin-vue-admin&chart=bubble&latestMonth=3" target="_blank" alt="Contribution Leaderboard" style="display: block; width: 100%;" />
</a>
## 9. 捐赠
如果你觉得这个项目对你有帮助,你可以请作者喝饮料 :tropical_drink: [点我](https://www.gin-vue-admin.com/coffee/index.html)
## 10. 注意事项
请严格遵守Apache 2.0协议并保留作品声明,去除版权信息请务必[获取授权](https://plugin.gin-vue-admin.com/license)
未授权去除版权信息将依法追究法律责任
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Reporting a Vulnerability
Please report security issues to qimiaojiangjizhao@gmail.com
================================================
FILE: deploy/docker/Dockerfile
================================================
FROM centos:7
WORKDIR /opt
ENV LANG=en_US.utf8
COPY deploy/docker/entrypoint.sh .
COPY build/ /usr/share/nginx/html/
COPY server/config.yaml /usr/share/nginx/html/config.yaml
COPY web/.docker-compose/nginx/conf.d/nginx.conf /etc/nginx/conf.d/nginx.conf
RUN set -ex \
&& echo "LANG=en_US.utf8" > /etc/locale.conf \
&& echo "net.core.somaxconn = 1024" >> /etc/sysctl.conf \
&& echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf \
&& yum -y install epel-release \
&& yum -y localinstall http://mirrors.ustc.edu.cn/mysql-repo/mysql57-community-release-el7.rpm \
&& yum -y install mysql-community-server git redis nginx go npm --nogpgcheck && chmod +x ./entrypoint.sh \
&& npm install -g yarn && go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct \
&& echo "start" > /dev/null
EXPOSE 80
ENTRYPOINT ["./entrypoint.sh"]
================================================
FILE: deploy/docker/entrypoint.sh
================================================
#!/bin/bash
if [ ! -d "/var/lib/mysql/gva" ]; then
mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
mysqld --daemonize --user=mysql
sleep 5s
mysql -uroot -e "create database gva default charset 'utf8' collate 'utf8_bin'; grant all on gva.* to 'root'@'127.0.0.1' identified by '123456'; flush privileges;"
else
mysqld --daemonize --user=mysql
fi
redis-server &
if [ "$1" = "actions" ]; then
cd /opt/gva/server && go run main.go &
cd /opt/gva/web/ && yarn serve &
else
/usr/sbin/nginx &
cd /usr/share/nginx/html/ && ./server &
fi
echo "gva ALL start!!!"
tail -f /dev/null
================================================
FILE: deploy/docker-compose/docker-compose.yaml
================================================
version: "3"
# 声明一个名为network的networks,subnet为network的子网地址,默认网关是177.7.0.1
networks:
network:
ipam:
driver: default
config:
- subnet: '177.7.0.0/16'
# 设置mysql,redis持久化保存
volumes:
mysql:
redis:
services:
web:
build:
context: ../../web
dockerfile: ./Dockerfile
container_name: gva-web
restart: always
ports:
- '8080:8080'
depends_on:
- server
command: [ 'nginx-debug', '-g', 'daemon off;' ]
networks:
network:
ipv4_address: 177.7.0.11
server:
build:
context: ../../server
dockerfile: ./Dockerfile
container_name: gva-server
restart: always
ports:
- '8888:8888'
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
links:
- mysql
- redis
networks:
network:
ipv4_address: 177.7.0.12
mysql:
image: mysql:8.0.21 # 如果您是 arm64 架构:如 MacOS 的 M1,请修改镜像为 image: mysql/mysql-server:8.0.21
container_name: gva-mysql
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci #设置utf8字符集
restart: always
ports:
- "13306:3306" # host物理直接映射端口为13306
environment:
#MYSQL_ROOT_PASSWORD: 'Aa@6447985' # root管理员用户密码
MYSQL_DATABASE: 'qmPlus' # 初始化启动时要创建的数据库的名称
MYSQL_USER: 'gva'
MYSQL_PASSWORD: 'Aa@6447985'
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "gva", "-pAa@6447985"]
interval: 10s
timeout: 5s
retries: 3
volumes:
- mysql:/var/lib/mysql
networks:
network:
ipv4_address: 177.7.0.13
redis:
image: redis:6.0.6
container_name: gva-redis # 容器名
restart: always
ports:
- '16379:6379'
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG || exit 1"]
interval: 10s
timeout: 5s
retries: 3
volumes:
- redis:/data
networks:
network:
ipv4_address: 177.7.0.14
================================================
FILE: deploy/kubernetes/server/gva-server-configmap.yaml
================================================
apiVersion: v1
kind: ConfigMap
metadata:
name: config.yaml
annotations:
flipped-aurora/gin-vue-admin: backend
github: "https://github.com/flipped-aurora/gin-vue-admin.git"
app.kubernetes.io/version: 0.0.1
labels:
app: gva-server
version: gva-vue3
data:
config.yaml: |
# github.com/flipped-aurora/gin-vue-admin/server Global Configuration
# jwt configuration
jwt:
signing-key: 'qmPlus'
expires-time: 604800
buffer-time: 86400
# zap logger configuration
zap:
level: 'info'
format: 'console'
prefix: '[github.com/flipped-aurora/gin-vue-admin/server]'
director: 'log'
link-name: 'latest_log'
show-line: true
encode-level: 'LowercaseColorLevelEncoder'
stacktrace-key: 'stacktrace'
log-in-console: true
# redis configuration
redis:
db: 0
addr: '127.0.0.1:6379'
password: ''
# email configuration
email:
to: 'xxx@qq.com'
port: 465
from: 'xxx@163.com'
host: 'smtp.163.com'
is-ssl: true
secret: 'xxx'
nickname: 'test'
# casbin configuration
casbin:
model-path: './resource/rbac_model.conf'
# system configuration
system:
env: 'develop' # Change to "develop" to skip authentication for development mode
addr: 8888
db-type: 'mysql'
oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
use-multipoint: false
# captcha configuration
captcha:
key-long: 6
img-width: 240
img-height: 80
# mysql connect configuration
# 未初始化之前请勿手动修改数据库信息!!!如果一定要手动初始化请看(https://www.github.com/flipped-aurora/gin-vue-admin/server.com/docs/first)
mysql:
path: ''
config: ''
db-name: ''
username: ''
password: ''
max-idle-conns: 10
max-open-conns: 100
log-mode: false
log-zap: ""
# local configuration
local:
path: 'uploads/file'
# autocode configuration
autocode:
transfer-restart: true
root: ""
server: /server
server-api: /api/v1/autocode
server-initialize: /initialize
server-model: /model/autocode
server-request: /model/autocode/request/
server-router: /router/autocode
server-service: /service/autocode
web: /web/src
web-api: /api
web-flow: /view
web-form: /view
web-table: /view
# qiniu configuration (请自行七牛申请对应的 公钥 私钥 bucket 和 域名地址)
qiniu:
zone: 'ZoneHuaDong'
bucket: ''
img-path: ''
use-https: false
access-key: ''
secret-key: ''
use-cdn-domains: false
# aliyun oss configuration
aliyun-oss:
endpoint: 'yourEndpoint'
access-key-id: 'yourAccessKeyId'
access-key-secret: 'yourAccessKeySecret'
bucket-name: 'yourBucketName'
bucket-url: 'yourBucketUrl'
base-path: 'yourBasePath'
# tencent cos configuration
tencent-cos:
bucket: 'xxxxx-10005608'
region: 'ap-shanghai'
secret-id: 'xxxxxxxx'
secret-key: 'xxxxxxxx'
base-url: 'https://gin.vue.admin'
path-prefix: 'github.com/flipped-aurora/gin-vue-admin/server'
# excel configuration
excel:
dir: './resource/excel/'
# timer task db clear table
Timer:
start: true
spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron/v3
detail: [
# tableName: 需要清理的表名
# compareField: 需要比较时间的字段
# interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数
# 2160h = 24 * 30 * 3 -> 三个月
{ tableName: "sys_operation_records" , compareField: "created_at", interval: "2160h" },
{ tableName: "jwt_blacklists" , compareField: "created_at", interval: "168h" }
#{ tableName: "log2" , compareField: "created_at", interval: "2160h" }
]
================================================
FILE: deploy/kubernetes/server/gva-server-deployment.yaml
================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: gva-server
annotations:
flipped-aurora/gin-vue-admin: backend
github: "https://github.com/flipped-aurora/gin-vue-admin.git"
app.kubernetes.io/version: 0.0.1
labels:
app: gva-server
version: gva-vue3
spec:
replicas: 1
selector:
matchLabels:
app: gva-server
version: gva-vue3
template:
metadata:
labels:
app: gva-server
version: gva-vue3
spec:
containers:
- name: gin-vue-admin-container
image: registry.cn-hangzhou.aliyuncs.com/gva/server:latest
imagePullPolicy: Always
ports:
- containerPort: 8888
name: http
volumeMounts:
- mountPath: /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml
name: config
subPath: config.yaml
- mountPath: /etc/localtime
name: localtime
resources:
limits:
cpu: 1000m
memory: 2000Mi
requests:
cpu: 100m
memory: 200Mi
livenessProbe:
failureThreshold: 1
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 8888
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 8888
timeoutSeconds: 1
startupProbe:
failureThreshold: 40
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 8888
timeoutSeconds: 1
#imagePullSecrets:
# - name: docker-registry
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: config
configMap:
name: config.yaml
================================================
FILE: deploy/kubernetes/server/gva-server-service.yaml
================================================
apiVersion: v1
kind: Service
metadata:
name: gva-server
annotations:
flipped-aurora/gin-vue-admin: backend
github: "https://github.com/flipped-aurora/gin-vue-admin.git"
app.kubernetes.io/version: 0.0.1
labels:
app: gva-server
version: gva-vue3
spec:
selector:
app: gva-server
version: gva-vue3
ports:
- port: 8888
name: http
targetPort: 8888
type: ClusterIP
# type: NodePort
================================================
FILE: deploy/kubernetes/web/gva-web-configmap.yaml
================================================
apiVersion: v1
kind: ConfigMap
metadata:
name: my.conf
data:
my.conf: |
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
try_files $uri $uri/ /index.html;
}
location /api {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^/api/(.*)$ /$1 break; #重写
proxy_pass http://gva-server:8888; # 设置代理服务器的协议和地址
}
location /api/swagger/index.html {
proxy_pass http://gva-server:8888/swagger/index.html;
}
}
================================================
FILE: deploy/kubernetes/web/gva-web-deploymemt.yaml
================================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: gva-web
annotations:
flipped-aurora/gin-vue-admin: ui
github: "https://github.com/flipped-aurora/gin-vue-admin.git"
app.kubernetes.io/version: 0.0.1
labels:
app: gva-web
version: gva-vue3
spec:
replicas: 1
selector:
matchLabels:
app: gva-web
version: gva-vue3
template:
metadata:
labels:
app: gva-web
version: gva-vue3
spec:
containers:
- name: gin-vue-admin-nginx-container
image: registry.cn-hangzhou.aliyuncs.com/gva/web:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
resources:
limits:
cpu: 500m
memory: 1000Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- mountPath: /etc/nginx/conf.d/
name: nginx-config
volumes:
- name: nginx-config
configMap:
name: my.conf
================================================
FILE: deploy/kubernetes/web/gva-web-ingress.yaml
================================================
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gva-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: demo.gin-vue-admin.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gva-web
port:
number: 8080
================================================
FILE: deploy/kubernetes/web/gva-web-service.yaml
================================================
apiVersion: v1
kind: Service
metadata:
name: gva-web
annotations:
flipped-aurora/gin-vue-admin: ui
github: "https://github.com/flipped-aurora/gin-vue-admin.git"
app.kubernetes.io/version: 0.0.1
labels:
app: gva-web
version: gva-vue3
spec:
# type: NodePort
type: ClusterIP
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: gva-web
version: gva-vue3
================================================
FILE: gin-vue-admin.code-workspace
================================================
{
"folders": [
{
"path": "server",
"name": "backend"
},
{
"path": "web",
"name": "frontend"
},
{
"path": ".",
"name": "root"
}
],
"settings": {
"go.toolsEnvVars": {
"GOPROXY": "https://goproxy.cn,direct",
"GONOPROXY": "none;"
}
},
"launch": {
"version": "0.2.0",
"configurations": [
{
"type": "go",
"request": "launch",
"name": "Backend",
"cwd": "${workspaceFolder:backend}",
"program": "${workspaceFolder:backend}/"
},
{
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder:frontend}",
"name": "Frontend",
"runtimeExecutable": "npm",
"runtimeArgs": ["run-script", "serve"]
}
],
"compounds": [
{
"name": "Both (Backend & Frontend)",
"configurations": ["Backend", "Frontend"],
"stopAll": true
}
]
}
}
================================================
FILE: server/Dockerfile
================================================
FROM golang:alpine as builder
WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server
COPY . .
RUN go env -w GO111MODULE=on \
&& go env -w GOPROXY=https://goproxy.cn,direct \
&& go env -w CGO_ENABLED=0 \
&& go env \
&& go mod tidy \
&& go build -o server .
FROM alpine:latest
LABEL MAINTAINER="SliverHorn@sliver_horn@qq.com"
# 设置时区
ENV TZ=Asia/Shanghai
RUN apk update && apk add --no-cache tzdata openntpd \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/server ./
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/resource ./resource/
COPY --from=0 /go/src/github.com/flipped-aurora/gin-vue-admin/server/config.docker.yaml ./
# 挂载目录:如果使用了sqlite数据库,容器命令示例:docker run -d -v /宿主机路径/gva.db:/go/src/github.com/flipped-aurora/gin-vue-admin/server/gva.db -p 8888:8888 --name gva-server-v1 gva-server:1.0
# VOLUME ["/go/src/github.com/flipped-aurora/gin-vue-admin/server"]
EXPOSE 8888
ENTRYPOINT ./server -c config.docker.yaml
================================================
FILE: server/README.md
================================================
## server项目结构
```shell
├── api
│ └── v1
├── config
├── core
├── docs
├── global
├── initialize
│ └── internal
├── middleware
├── model
│ ├── request
│ └── response
├── packfile
├── resource
│ ├── excel
│ ├── page
│ └── template
├── router
├── service
├── source
└── utils
├── timer
└── upload
```
| 文件夹 | 说明 | 描述 |
| ------------ | ----------------------- | --------------------------- |
| `api` | api层 | api层 |
| `--v1` | v1版本接口 | v1版本接口 |
| `config` | 配置包 | config.yaml对应的配置结构体 |
| `core` | 核心文件 | 核心组件(zap, viper, server)的初始化 |
| `docs` | swagger文档目录 | swagger文档目录 |
| `global` | 全局对象 | 全局对象 |
| `initialize` | 初始化 | router,redis,gorm,validator, timer的初始化 |
| `--internal` | 初始化内部函数 | gorm 的 longger 自定义,在此文件夹的函数只能由 `initialize` 层进行调用 |
| `middleware` | 中间件层 | 用于存放 `gin` 中间件代码 |
| `model` | 模型层 | 模型对应数据表 |
| `--request` | 入参结构体 | 接收前端发送到后端的数据。 |
| `--response` | 出参结构体 | 返回给前端的数据结构体 |
| `packfile` | 静态文件打包 | 静态文件打包 |
| `resource` | 静态资源文件夹 | 负责存放静态文件 |
| `--excel` | excel导入导出默认路径 | excel导入导出默认路径 |
| `--page` | 表单生成器 | 表单生成器 打包后的dist |
| `--template` | 模板 | 模板文件夹,存放的是代码生成器的模板 |
| `router` | 路由层 | 路由层 |
| `service` | service层 | 存放业务逻辑问题 |
| `source` | source层 | 存放初始化数据的函数 |
| `utils` | 工具包 | 工具函数封装 |
| `--timer` | timer | 定时器接口封装 |
| `--upload` | oss | oss接口封装 |
================================================
FILE: server/api/v1/enter.go
================================================
package v1
import (
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/example"
"github.com/flipped-aurora/gin-vue-admin/server/api/v1/system"
)
var ApiGroupApp = new(ApiGroup)
type ApiGroup struct {
SystemApiGroup system.ApiGroup
ExampleApiGroup example.ApiGroup
}
================================================
FILE: server/api/v1/example/enter.go
================================================
package example
import "github.com/flipped-aurora/gin-vue-admin/server/service"
type ApiGroup struct {
CustomerApi
FileUploadAndDownloadApi
AttachmentCategoryApi
}
var (
customerService = service.ServiceGroupApp.ExampleServiceGroup.CustomerService
fileUploadAndDownloadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService
attachmentCategoryService = service.ServiceGroupApp.ExampleServiceGroup.AttachmentCategoryService
)
================================================
FILE: server/api/v1/example/exa_attachment_category.go
================================================
package example
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AttachmentCategoryApi struct{}
// GetCategoryList
// @Tags GetCategoryList
// @Summary 媒体库分类列表
// @Security AttachmentCategory
// @Produce application/json
// @Success 200 {object} response.Response{data=example.ExaAttachmentCategory,msg=string} "媒体库分类列表"
// @Router /attachmentCategory/getCategoryList [get]
func (a *AttachmentCategoryApi) GetCategoryList(c *gin.Context) {
res, err := attachmentCategoryService.GetCategoryList()
if err != nil {
global.GVA_LOG.Error("获取分类列表失败!", zap.Error(err))
response.FailWithMessage("获取分类列表失败", c)
return
}
response.OkWithData(res, c)
}
// AddCategory
// @Tags AddCategory
// @Summary 添加媒体库分类
// @Security AttachmentCategory
// @accept application/json
// @Produce application/json
// @Param data body example.ExaAttachmentCategory true "媒体库分类数据"// @Success 200 {object} response.Response{msg=string} "添加媒体库分类"
// @Router /attachmentCategory/addCategory [post]
func (a *AttachmentCategoryApi) AddCategory(c *gin.Context) {
var req example.ExaAttachmentCategory
if err := c.ShouldBindJSON(&req); err != nil {
global.GVA_LOG.Error("参数错误!", zap.Error(err))
response.FailWithMessage("参数错误", c)
return
}
if err := attachmentCategoryService.AddCategory(&req); err != nil {
global.GVA_LOG.Error("创建/更新失败!", zap.Error(err))
response.FailWithMessage("创建/更新失败:"+err.Error(), c)
return
}
response.OkWithMessage("创建/更新成功", c)
}
// DeleteCategory
// @Tags DeleteCategory
// @Summary 删除分类
// @Security AttachmentCategory
// @accept application/json
// @Produce application/json
// @Param data body common.GetById true "分类id"
// @Success 200 {object} response.Response{msg=string} "删除分类"
// @Router /attachmentCategory/deleteCategory [post]
func (a *AttachmentCategoryApi) DeleteCategory(c *gin.Context) {
var req common.GetById
if err := c.ShouldBindJSON(&req); err != nil {
response.FailWithMessage("参数错误", c)
return
}
if req.ID == 0 {
response.FailWithMessage("参数错误", c)
return
}
if err := attachmentCategoryService.DeleteCategory(&req.ID); err != nil {
response.FailWithMessage("删除失败", c)
return
}
response.OkWithMessage("删除成功", c)
}
================================================
FILE: server/api/v1/example/exa_breakpoint_continue.go
================================================
package example
import (
"fmt"
"io"
"mime/multipart"
"strconv"
"strings"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/model/example/response"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// BreakpointContinue
// @Tags ExaFileUploadAndDownload
// @Summary 断点续传到服务器
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "an example for breakpoint resume, 断点续传示例"
// @Success 200 {object} response.Response{msg=string} "断点续传到服务器"
// @Router /fileUploadAndDownload/breakpointContinue [post]
func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
fileMd5 := c.Request.FormValue("fileMd5")
fileName := c.Request.FormValue("fileName")
chunkMd5 := c.Request.FormValue("chunkMd5")
chunkNumber, _ := strconv.Atoi(c.Request.FormValue("chunkNumber"))
chunkTotal, _ := strconv.Atoi(c.Request.FormValue("chunkTotal"))
_, FileHeader, err := c.Request.FormFile("file")
if err != nil {
global.GVA_LOG.Error("接收文件失败!", zap.Error(err))
response.FailWithMessage("接收文件失败", c)
return
}
f, err := FileHeader.Open()
if err != nil {
global.GVA_LOG.Error("文件读取失败!", zap.Error(err))
response.FailWithMessage("文件读取失败", c)
return
}
defer func(f multipart.File) {
err := f.Close()
if err != nil {
fmt.Println(err)
}
}(f)
cen, _ := io.ReadAll(f)
if !utils.CheckMd5(cen, chunkMd5) {
global.GVA_LOG.Error("检查md5失败!", zap.Error(err))
response.FailWithMessage("检查md5失败", c)
return
}
file, err := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
if err != nil {
global.GVA_LOG.Error("查找或创建记录失败!", zap.Error(err))
response.FailWithMessage("查找或创建记录失败", c)
return
}
pathC, err := utils.BreakPointContinue(cen, fileName, chunkNumber, chunkTotal, fileMd5)
if err != nil {
global.GVA_LOG.Error("断点续传失败!", zap.Error(err))
response.FailWithMessage("断点续传失败", c)
return
}
if err = fileUploadAndDownloadService.CreateFileChunk(file.ID, pathC, chunkNumber); err != nil {
global.GVA_LOG.Error("创建文件记录失败!", zap.Error(err))
response.FailWithMessage("创建文件记录失败", c)
return
}
response.OkWithMessage("切片创建成功", c)
}
// FindFile
// @Tags ExaFileUploadAndDownload
// @Summary 查找文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "Find the file, 查找文件"
// @Success 200 {object} response.Response{data=exampleRes.FileResponse,msg=string} "查找文件,返回包括文件详情"
// @Router /fileUploadAndDownload/findFile [get]
func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
chunkTotal, _ := strconv.Atoi(c.Query("chunkTotal"))
file, err := fileUploadAndDownloadService.FindOrCreateFile(fileMd5, fileName, chunkTotal)
if err != nil {
global.GVA_LOG.Error("查找失败!", zap.Error(err))
response.FailWithMessage("查找失败", c)
} else {
response.OkWithDetailed(exampleRes.FileResponse{File: file}, "查找成功", c)
}
}
// BreakpointContinueFinish
// @Tags ExaFileUploadAndDownload
// @Summary 创建文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "上传文件完成"
// @Success 200 {object} response.Response{data=exampleRes.FilePathResponse,msg=string} "创建文件,返回包括文件路径"
// @Router /fileUploadAndDownload/findFile [post]
func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Context) {
fileMd5 := c.Query("fileMd5")
fileName := c.Query("fileName")
filePath, err := utils.MakeFile(fileName, fileMd5)
if err != nil {
global.GVA_LOG.Error("文件创建失败!", zap.Error(err))
response.FailWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建失败", c)
} else {
response.OkWithDetailed(exampleRes.FilePathResponse{FilePath: filePath}, "文件创建成功", c)
}
}
// RemoveChunk
// @Tags ExaFileUploadAndDownload
// @Summary 删除切片
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "删除缓存切片"
// @Success 200 {object} response.Response{msg=string} "删除切片"
// @Router /fileUploadAndDownload/removeChunk [post]
func (b *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
var file example.ExaFile
err := c.ShouldBindJSON(&file)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
// 路径穿越拦截
if strings.Contains(file.FilePath, "..") || strings.Contains(file.FilePath, "../") || strings.Contains(file.FilePath, "./") || strings.Contains(file.FilePath, ".\\") {
response.FailWithMessage("非法路径,禁止删除", c)
return
}
err = utils.RemoveChunk(file.FileMd5)
if err != nil {
global.GVA_LOG.Error("缓存切片删除失败!", zap.Error(err))
return
}
err = fileUploadAndDownloadService.DeleteFileChunk(file.FileMd5, file.FilePath)
if err != nil {
global.GVA_LOG.Error(err.Error(), zap.Error(err))
response.FailWithMessage(err.Error(), c)
return
}
response.OkWithMessage("缓存切片删除成功", c)
}
================================================
FILE: server/api/v1/example/exa_customer.go
================================================
package example
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/model/example"
exampleRes "github.com/flipped-aurora/gin-vue-admin/server/model/example/response"
"github.com/flipped-aurora/gin-vue-admin/server/utils"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type CustomerApi struct{}
// CreateExaCustomer
// @Tags ExaCustomer
// @Summary 创建客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户用户名, 客户手机号码"
// @Success 200 {object} response.Response{msg=string} "创建客户"
// @Router /customer/customer [post]
func (e *CustomerApi) CreateExaCustomer(c *gin.Context) {
var customer example.ExaCustomer
err := c.ShouldBindJSON(&customer)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
err = utils.Verify(customer, utils.CustomerVerify)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
customer.SysUserID = utils.GetUserID(c)
customer.SysUserAuthorityID = utils.GetUserAuthorityId(c)
err = customerService.CreateExaCustomer(customer)
if err != nil {
global.GVA_LOG.Error("创建失败!", zap.Error(err))
response.FailWithMessage("创建失败", c)
return
}
response.OkWithMessage("创建成功", c)
}
// DeleteExaCustomer
// @Tags ExaCustomer
// @Summary 删除客户
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body example.ExaCustomer true "客户ID"
// @Success 200 {object} response.Response{msg=string} "删除客户"
// @Router /customer
gitextract_u70pmzr2/
├── .aone_copilot/
│ └── rules/
│ └── project_rules.md
├── .claude/
│ └── rules/
│ └── project_rules.md
├── .codex/
│ └── rules/
│ └── project_rules.md
├── .cursor/
│ └── rules/
│ └── project_rules.md
├── .gitattributes
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yaml
│ │ ├── config.yml
│ │ └── feature_request.yaml
│ └── workflows/
│ └── ci.yaml
├── .gitignore
├── .trae/
│ └── rules/
│ └── project_rules.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README-en.md
├── README.md
├── SECURITY.md
├── deploy/
│ ├── docker/
│ │ ├── Dockerfile
│ │ └── entrypoint.sh
│ ├── docker-compose/
│ │ └── docker-compose.yaml
│ └── kubernetes/
│ ├── server/
│ │ ├── gva-server-configmap.yaml
│ │ ├── gva-server-deployment.yaml
│ │ └── gva-server-service.yaml
│ └── web/
│ ├── gva-web-configmap.yaml
│ ├── gva-web-deploymemt.yaml
│ ├── gva-web-ingress.yaml
│ └── gva-web-service.yaml
├── gin-vue-admin.code-workspace
├── server/
│ ├── Dockerfile
│ ├── README.md
│ ├── api/
│ │ └── v1/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── auto_code_history.go
│ │ ├── auto_code_mcp.go
│ │ ├── auto_code_package.go
│ │ ├── auto_code_plugin.go
│ │ ├── auto_code_template.go
│ │ ├── enter.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code.go
│ │ ├── sys_captcha.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_jwt_blacklist.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── config/
│ │ ├── auto_code.go
│ │ ├── captcha.go
│ │ ├── config.go
│ │ ├── cors.go
│ │ ├── db_list.go
│ │ ├── disk.go
│ │ ├── email.go
│ │ ├── excel.go
│ │ ├── gorm_mssql.go
│ │ ├── gorm_mysql.go
│ │ ├── gorm_oracle.go
│ │ ├── gorm_pgsql.go
│ │ ├── gorm_sqlite.go
│ │ ├── jwt.go
│ │ ├── mcp.go
│ │ ├── mongo.go
│ │ ├── oss_aliyun.go
│ │ ├── oss_aws.go
│ │ ├── oss_cloudflare.go
│ │ ├── oss_huawei.go
│ │ ├── oss_local.go
│ │ ├── oss_minio.go
│ │ ├── oss_qiniu.go
│ │ ├── oss_tencent.go
│ │ ├── redis.go
│ │ ├── system.go
│ │ └── zap.go
│ ├── config.docker.yaml
│ ├── config.yaml
│ ├── core/
│ │ ├── internal/
│ │ │ ├── constant.go
│ │ │ ├── cutter.go
│ │ │ └── zap_core.go
│ │ ├── server.go
│ │ ├── server_run.go
│ │ ├── viper.go
│ │ └── zap.go
│ ├── docs/
│ │ ├── docs.go
│ │ ├── swagger.json
│ │ └── swagger.yaml
│ ├── global/
│ │ ├── global.go
│ │ ├── model.go
│ │ └── version.go
│ ├── go.mod
│ ├── go.sum
│ ├── initialize/
│ │ ├── db_list.go
│ │ ├── ensure_tables.go
│ │ ├── gorm.go
│ │ ├── gorm_biz.go
│ │ ├── gorm_mssql.go
│ │ ├── gorm_mysql.go
│ │ ├── gorm_oracle.go
│ │ ├── gorm_pgsql.go
│ │ ├── gorm_sqlite.go
│ │ ├── init.go
│ │ ├── internal/
│ │ │ ├── gorm.go
│ │ │ ├── gorm_logger_writer.go
│ │ │ └── mongo.go
│ │ ├── mcp.go
│ │ ├── mongo.go
│ │ ├── other.go
│ │ ├── plugin.go
│ │ ├── plugin_biz_v1.go
│ │ ├── plugin_biz_v2.go
│ │ ├── redis.go
│ │ ├── register_init.go
│ │ ├── reload.go
│ │ ├── router.go
│ │ ├── router_biz.go
│ │ ├── timer.go
│ │ └── validator.go
│ ├── main.go
│ ├── mcp/
│ │ ├── api_creator.go
│ │ ├── api_lister.go
│ │ ├── client/
│ │ │ ├── client.go
│ │ │ └── client_test.go
│ │ ├── dictionary_generator.go
│ │ ├── dictionary_query.go
│ │ ├── enter.go
│ │ ├── gva_analyze.go
│ │ ├── gva_execute.go
│ │ ├── gva_review.go
│ │ ├── menu_creator.go
│ │ ├── menu_lister.go
│ │ └── requirement_analyzer.go
│ ├── middleware/
│ │ ├── casbin_rbac.go
│ │ ├── cors.go
│ │ ├── email.go
│ │ ├── error.go
│ │ ├── jwt.go
│ │ ├── limit_ip.go
│ │ ├── loadtls.go
│ │ ├── logger.go
│ │ ├── operation.go
│ │ └── timeout.go
│ ├── model/
│ │ ├── common/
│ │ │ ├── basetypes.go
│ │ │ ├── clearDB.go
│ │ │ ├── request/
│ │ │ │ └── common.go
│ │ │ └── response/
│ │ │ ├── common.go
│ │ │ └── response.go
│ │ ├── example/
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ ├── exa_file_upload_download.go
│ │ │ ├── request/
│ │ │ │ └── exa_file_upload_and_downloads.go
│ │ │ └── response/
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── request/
│ │ │ ├── jwt.go
│ │ │ ├── sys_api.go
│ │ │ ├── sys_api_token.go
│ │ │ ├── sys_authority_btn.go
│ │ │ ├── sys_auto_code.go
│ │ │ ├── sys_auto_code_mcp.go
│ │ │ ├── sys_auto_code_package.go
│ │ │ ├── sys_auto_history.go
│ │ │ ├── sys_casbin.go
│ │ │ ├── sys_dictionary.go
│ │ │ ├── sys_dictionary_detail.go
│ │ │ ├── sys_error.go
│ │ │ ├── sys_export_template.go
│ │ │ ├── sys_init.go
│ │ │ ├── sys_login_log.go
│ │ │ ├── sys_menu.go
│ │ │ ├── sys_operation_record.go
│ │ │ ├── sys_params.go
│ │ │ ├── sys_skills.go
│ │ │ ├── sys_user.go
│ │ │ └── sys_version.go
│ │ ├── response/
│ │ │ ├── sys_api.go
│ │ │ ├── sys_authority.go
│ │ │ ├── sys_authority_btn.go
│ │ │ ├── sys_auto_code.go
│ │ │ ├── sys_captcha.go
│ │ │ ├── sys_casbin.go
│ │ │ ├── sys_menu.go
│ │ │ ├── sys_system.go
│ │ │ ├── sys_user.go
│ │ │ └── sys_version.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_authority_menu.go
│ │ ├── sys_auto_code_history.go
│ │ ├── sys_auto_code_package.go
│ │ ├── sys_base_menu.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_jwt_blacklist.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu_btn.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ ├── sys_user_authority.go
│ │ └── sys_version.go
│ ├── plugin/
│ │ ├── announcement/
│ │ │ ├── api/
│ │ │ │ ├── enter.go
│ │ │ │ └── info.go
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── gen/
│ │ │ │ └── gen.go
│ │ │ ├── initialize/
│ │ │ │ ├── api.go
│ │ │ │ ├── dictionary.go
│ │ │ │ ├── gorm.go
│ │ │ │ ├── menu.go
│ │ │ │ ├── router.go
│ │ │ │ └── viper.go
│ │ │ ├── model/
│ │ │ │ ├── info.go
│ │ │ │ └── request/
│ │ │ │ └── info.go
│ │ │ ├── plugin/
│ │ │ │ └── plugin.go
│ │ │ ├── plugin.go
│ │ │ ├── router/
│ │ │ │ ├── enter.go
│ │ │ │ └── info.go
│ │ │ └── service/
│ │ │ ├── enter.go
│ │ │ └── info.go
│ │ ├── email/
│ │ │ ├── README.MD
│ │ │ ├── api/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ ├── config/
│ │ │ │ └── email.go
│ │ │ ├── global/
│ │ │ │ └── gloabl.go
│ │ │ ├── main.go
│ │ │ ├── model/
│ │ │ │ └── response/
│ │ │ │ └── email.go
│ │ │ ├── router/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ ├── service/
│ │ │ │ ├── enter.go
│ │ │ │ └── sys_email.go
│ │ │ └── utils/
│ │ │ └── email.go
│ │ ├── plugin-tool/
│ │ │ └── utils/
│ │ │ └── check.go
│ │ └── register.go
│ ├── resource/
│ │ ├── function/
│ │ │ ├── api.go.tpl
│ │ │ ├── api.js.tpl
│ │ │ └── server.go.tpl
│ │ ├── mcp/
│ │ │ └── tools.tpl
│ │ ├── package/
│ │ │ ├── readme.txt.tpl
│ │ │ ├── server/
│ │ │ │ ├── api/
│ │ │ │ │ ├── api.go.tpl
│ │ │ │ │ └── enter.go.tpl
│ │ │ │ ├── model/
│ │ │ │ │ ├── model.go.tpl
│ │ │ │ │ └── request/
│ │ │ │ │ └── request.go.tpl
│ │ │ │ ├── router/
│ │ │ │ │ ├── enter.go.tpl
│ │ │ │ │ └── router.go.tpl
│ │ │ │ └── service/
│ │ │ │ ├── enter.go.tpl
│ │ │ │ └── service.go.tpl
│ │ │ └── web/
│ │ │ ├── api/
│ │ │ │ └── api.js.tpl
│ │ │ └── view/
│ │ │ ├── form.vue.tpl
│ │ │ └── table.vue.tpl
│ │ └── plugin/
│ │ ├── server/
│ │ │ ├── api/
│ │ │ │ ├── api.go.tpl
│ │ │ │ └── enter.go.tpl
│ │ │ ├── config/
│ │ │ │ └── config.go.tpl
│ │ │ ├── gen/
│ │ │ │ └── gen.go.tpl
│ │ │ ├── initialize/
│ │ │ │ ├── api.go.tpl
│ │ │ │ ├── dictionary.go.tpl
│ │ │ │ ├── gorm.go.tpl
│ │ │ │ ├── menu.go.tpl
│ │ │ │ ├── router.go.tpl
│ │ │ │ └── viper.go.tpl
│ │ │ ├── model/
│ │ │ │ ├── model.go.tpl
│ │ │ │ └── request/
│ │ │ │ └── request.go.tpl
│ │ │ ├── plugin/
│ │ │ │ └── plugin.go.tpl
│ │ │ ├── plugin.go.tpl
│ │ │ ├── router/
│ │ │ │ ├── enter.go.tpl
│ │ │ │ └── router.go.tpl
│ │ │ └── service/
│ │ │ ├── enter.go.tpl
│ │ │ └── service.go.tpl
│ │ └── web/
│ │ ├── api/
│ │ │ └── api.js.tpl
│ │ ├── form/
│ │ │ └── form.vue.tpl
│ │ └── view/
│ │ └── view.vue.tpl
│ ├── router/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_and_download.go
│ │ └── system/
│ │ ├── enter.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code.go
│ │ ├── sys_auto_code_history.go
│ │ ├── sys_base.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_jwt.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── service/
│ │ ├── enter.go
│ │ ├── example/
│ │ │ ├── enter.go
│ │ │ ├── exa_attachment_category.go
│ │ │ ├── exa_breakpoint_continue.go
│ │ │ ├── exa_customer.go
│ │ │ └── exa_file_upload_download.go
│ │ └── system/
│ │ ├── auto_code_history.go
│ │ ├── auto_code_llm.go
│ │ ├── auto_code_mcp.go
│ │ ├── auto_code_package.go
│ │ ├── auto_code_package_test.go
│ │ ├── auto_code_plugin.go
│ │ ├── auto_code_template.go
│ │ ├── auto_code_template_test.go
│ │ ├── enter.go
│ │ ├── jwt_black_list.go
│ │ ├── sys_api.go
│ │ ├── sys_api_token.go
│ │ ├── sys_authority.go
│ │ ├── sys_authority_btn.go
│ │ ├── sys_auto_code_interface.go
│ │ ├── sys_auto_code_mssql.go
│ │ ├── sys_auto_code_mysql.go
│ │ ├── sys_auto_code_oracle.go
│ │ ├── sys_auto_code_pgsql.go
│ │ ├── sys_auto_code_sqlite.go
│ │ ├── sys_base_menu.go
│ │ ├── sys_casbin.go
│ │ ├── sys_dictionary.go
│ │ ├── sys_dictionary_detail.go
│ │ ├── sys_error.go
│ │ ├── sys_export_template.go
│ │ ├── sys_initdb.go
│ │ ├── sys_initdb_mssql.go
│ │ ├── sys_initdb_mysql.go
│ │ ├── sys_initdb_pgsql.go
│ │ ├── sys_initdb_sqlite.go
│ │ ├── sys_login_log.go
│ │ ├── sys_menu.go
│ │ ├── sys_operation_record.go
│ │ ├── sys_params.go
│ │ ├── sys_skills.go
│ │ ├── sys_system.go
│ │ ├── sys_user.go
│ │ └── sys_version.go
│ ├── source/
│ │ ├── example/
│ │ │ └── file_upload_download.go
│ │ └── system/
│ │ ├── api.go
│ │ ├── api_ignore.go
│ │ ├── authorities_menus.go
│ │ ├── authority.go
│ │ ├── casbin.go
│ │ ├── dictionary.go
│ │ ├── dictionary_detail.go
│ │ ├── excel_template.go
│ │ ├── menu.go
│ │ └── user.go
│ ├── task/
│ │ └── clearTable.go
│ └── utils/
│ ├── ast/
│ │ ├── ast.go
│ │ ├── ast_auto_enter.go
│ │ ├── ast_enter.go
│ │ ├── ast_gorm.go
│ │ ├── ast_init_test.go
│ │ ├── ast_rollback.go
│ │ ├── ast_router.go
│ │ ├── ast_test.go
│ │ ├── ast_type.go
│ │ ├── extract_func.go
│ │ ├── import.go
│ │ ├── interfaces.go
│ │ ├── interfaces_base.go
│ │ ├── package_enter.go
│ │ ├── package_enter_test.go
│ │ ├── package_initialize_gorm.go
│ │ ├── package_initialize_gorm_test.go
│ │ ├── package_initialize_router.go
│ │ ├── package_initialize_router_test.go
│ │ ├── package_module_enter.go
│ │ ├── package_module_enter_test.go
│ │ ├── plugin_enter.go
│ │ ├── plugin_enter_test.go
│ │ ├── plugin_gen.go
│ │ ├── plugin_gen_test.go
│ │ ├── plugin_initialize_gorm.go
│ │ ├── plugin_initialize_gorm_test.go
│ │ ├── plugin_initialize_router.go
│ │ ├── plugin_initialize_router_test.go
│ │ ├── plugin_initialize_v2.go
│ │ └── plugin_initialize_v2_test.go
│ ├── autocode/
│ │ └── template_funcs.go
│ ├── breakpoint_continue.go
│ ├── captcha/
│ │ └── redis.go
│ ├── casbin_util.go
│ ├── claims.go
│ ├── directory.go
│ ├── fmt_plus.go
│ ├── hash.go
│ ├── human_duration.go
│ ├── human_duration_test.go
│ ├── json.go
│ ├── json_test.go
│ ├── jwt.go
│ ├── plugin/
│ │ ├── plugin.go
│ │ └── v2/
│ │ ├── plugin.go
│ │ └── registry.go
│ ├── request/
│ │ └── http.go
│ ├── server.go
│ ├── stacktrace/
│ │ └── stacktrace.go
│ ├── system_events.go
│ ├── timer/
│ │ ├── timed_task.go
│ │ └── timed_task_test.go
│ ├── upload/
│ │ ├── aliyun_oss.go
│ │ ├── aws_s3.go
│ │ ├── cloudflare_r2.go
│ │ ├── local.go
│ │ ├── minio_oss.go
│ │ ├── obs.go
│ │ ├── qiniu.go
│ │ ├── tencent_cos.go
│ │ └── upload.go
│ ├── validator.go
│ ├── validator_test.go
│ ├── verify.go
│ └── zip.go
└── web/
├── .docker-compose/
│ └── nginx/
│ └── conf.d/
│ ├── my.conf
│ └── nginx.conf
├── .dockerignore
├── .gitignore
├── .prettierrc
├── Dockerfile
├── README.md
├── babel.config.js
├── eslint.config.mjs
├── index.html
├── jsconfig.json
├── limit.js
├── openDocument.js
├── package.json
├── src/
│ ├── App.vue
│ ├── api/
│ │ ├── api.js
│ │ ├── attachmentCategory.js
│ │ ├── authority.js
│ │ ├── authorityBtn.js
│ │ ├── autoCode.js
│ │ ├── breakpoint.js
│ │ ├── casbin.js
│ │ ├── customer.js
│ │ ├── email.js
│ │ ├── exportTemplate.js
│ │ ├── fileUploadAndDownload.js
│ │ ├── github.js
│ │ ├── initdb.js
│ │ ├── jwt.js
│ │ ├── menu.js
│ │ ├── plugin/
│ │ │ └── api.js
│ │ ├── skills.js
│ │ ├── sysApiToken.js
│ │ ├── sysDictionary.js
│ │ ├── sysDictionaryDetail.js
│ │ ├── sysLoginLog.js
│ │ ├── sysOperationRecord.js
│ │ ├── sysParams.js
│ │ ├── system/
│ │ │ └── sysError.js
│ │ ├── system.js
│ │ ├── user.js
│ │ └── version.js
│ ├── components/
│ │ ├── application/
│ │ │ └── index.vue
│ │ ├── arrayCtrl/
│ │ │ └── arrayCtrl.vue
│ │ ├── bottomInfo/
│ │ │ └── bottomInfo.vue
│ │ ├── charts/
│ │ │ └── index.vue
│ │ ├── commandMenu/
│ │ │ └── index.vue
│ │ ├── customPic/
│ │ │ └── index.vue
│ │ ├── errorPreview/
│ │ │ └── index.vue
│ │ ├── exportExcel/
│ │ │ ├── exportExcel.vue
│ │ │ ├── exportTemplate.vue
│ │ │ └── importExcel.vue
│ │ ├── logo/
│ │ │ └── index.vue
│ │ ├── office/
│ │ │ ├── docx.vue
│ │ │ ├── excel.vue
│ │ │ ├── index.vue
│ │ │ └── pdf.vue
│ │ ├── richtext/
│ │ │ ├── rich-edit.vue
│ │ │ └── rich-view.vue
│ │ ├── selectFile/
│ │ │ └── selectFile.vue
│ │ ├── selectImage/
│ │ │ ├── selectComponent.vue
│ │ │ └── selectImage.vue
│ │ ├── svgIcon/
│ │ │ └── svgIcon.vue
│ │ ├── upload/
│ │ │ ├── QR-code.vue
│ │ │ ├── common.vue
│ │ │ ├── cropper.vue
│ │ │ └── image.vue
│ │ └── warningBar/
│ │ └── warningBar.vue
│ ├── core/
│ │ ├── config.js
│ │ ├── error-handel.js
│ │ ├── gin-vue-admin.js
│ │ └── global.js
│ ├── directive/
│ │ ├── auth.js
│ │ └── clickOutSide.js
│ ├── hooks/
│ │ ├── charts.js
│ │ ├── responsive.js
│ │ └── use-windows-resize.js
│ ├── main.js
│ ├── pathInfo.json
│ ├── permission.js
│ ├── pinia/
│ │ ├── index.js
│ │ └── modules/
│ │ ├── app.js
│ │ ├── dictionary.js
│ │ ├── params.js
│ │ ├── router.js
│ │ └── user.js
│ ├── plugin/
│ │ ├── announcement/
│ │ │ ├── api/
│ │ │ │ └── info.js
│ │ │ ├── form/
│ │ │ │ └── info.vue
│ │ │ └── view/
│ │ │ └── info.vue
│ │ └── email/
│ │ ├── api/
│ │ │ └── email.js
│ │ └── view/
│ │ └── index.vue
│ ├── router/
│ │ └── index.js
│ ├── style/
│ │ ├── element/
│ │ │ └── index.scss
│ │ ├── element_visiable.scss
│ │ ├── iconfont.css
│ │ ├── main.scss
│ │ ├── reset.scss
│ │ └── transition.scss
│ ├── utils/
│ │ ├── asyncRouter.js
│ │ ├── btnAuth.js
│ │ ├── bus.js
│ │ ├── closeThisPage.js
│ │ ├── date.js
│ │ ├── dictionary.js
│ │ ├── doc.js
│ │ ├── downloadImg.js
│ │ ├── env.js
│ │ ├── event.js
│ │ ├── fmtRouterTitle.js
│ │ ├── format.js
│ │ ├── image.js
│ │ ├── page.js
│ │ ├── params.js
│ │ ├── request.js
│ │ └── stringFun.js
│ └── view/
│ ├── about/
│ │ └── index.vue
│ ├── dashboard/
│ │ ├── components/
│ │ │ ├── banner.vue
│ │ │ ├── card.vue
│ │ │ ├── charts-content-numbers.vue
│ │ │ ├── charts-people-numbers.vue
│ │ │ ├── charts.vue
│ │ │ ├── index.js
│ │ │ ├── notice.vue
│ │ │ ├── pluginTable.vue
│ │ │ ├── quickLinks.vue
│ │ │ ├── table.vue
│ │ │ └── wiki.vue
│ │ └── index.vue
│ ├── error/
│ │ ├── index.vue
│ │ └── reload.vue
│ ├── example/
│ │ ├── breakpoint/
│ │ │ └── breakpoint.vue
│ │ ├── customer/
│ │ │ └── customer.vue
│ │ ├── index.vue
│ │ └── upload/
│ │ ├── scanUpload.vue
│ │ └── upload.vue
│ ├── init/
│ │ └── index.vue
│ ├── layout/
│ │ ├── aside/
│ │ │ ├── asideComponent/
│ │ │ │ ├── asyncSubmenu.vue
│ │ │ │ ├── index.vue
│ │ │ │ └── menuItem.vue
│ │ │ ├── combinationMode.vue
│ │ │ ├── headMode.vue
│ │ │ ├── index.vue
│ │ │ ├── normalMode.vue
│ │ │ └── sidebarMode.vue
│ │ ├── header/
│ │ │ ├── index.vue
│ │ │ └── tools.vue
│ │ ├── iframe.vue
│ │ ├── index.vue
│ │ ├── screenfull/
│ │ │ └── index.vue
│ │ ├── search/
│ │ │ └── search.vue
│ │ ├── setting/
│ │ │ ├── components/
│ │ │ │ ├── layoutModeCard.vue
│ │ │ │ ├── settingItem.vue
│ │ │ │ ├── themeColorPicker.vue
│ │ │ │ └── themeModeSelector.vue
│ │ │ ├── index.vue
│ │ │ └── modules/
│ │ │ ├── appearance/
│ │ │ │ └── index.vue
│ │ │ ├── general/
│ │ │ │ └── index.vue
│ │ │ └── layout/
│ │ │ └── index.vue
│ │ └── tabs/
│ │ └── index.vue
│ ├── login/
│ │ └── index.vue
│ ├── person/
│ │ └── person.vue
│ ├── routerHolder.vue
│ ├── superAdmin/
│ │ ├── api/
│ │ │ └── api.vue
│ │ ├── authority/
│ │ │ ├── authority.vue
│ │ │ └── components/
│ │ │ ├── apis.vue
│ │ │ ├── datas.vue
│ │ │ └── menus.vue
│ │ ├── dictionary/
│ │ │ ├── sysDictionary.vue
│ │ │ └── sysDictionaryDetail.vue
│ │ ├── index.vue
│ │ ├── menu/
│ │ │ ├── components/
│ │ │ │ └── components-cascader.vue
│ │ │ ├── icon.vue
│ │ │ └── menu.vue
│ │ ├── operation/
│ │ │ └── sysOperationRecord.vue
│ │ ├── params/
│ │ │ └── sysParams.vue
│ │ └── user/
│ │ └── user.vue
│ ├── system/
│ │ └── state.vue
│ └── systemTools/
│ ├── apiToken/
│ │ └── index.vue
│ ├── autoCode/
│ │ ├── component/
│ │ │ ├── fieldDialog.vue
│ │ │ └── previewCodeDialog.vue
│ │ ├── index.vue
│ │ ├── mcp.vue
│ │ ├── mcpTest.vue
│ │ └── picture.vue
│ ├── autoCodeAdmin/
│ │ └── index.vue
│ ├── autoPkg/
│ │ └── autoPkg.vue
│ ├── exportTemplate/
│ │ ├── code.js
│ │ └── exportTemplate.vue
│ ├── formCreate/
│ │ └── index.vue
│ ├── index.vue
│ ├── installPlugin/
│ │ └── index.vue
│ ├── loginLog/
│ │ └── index.vue
│ ├── pubPlug/
│ │ └── pubPlug.vue
│ ├── skills/
│ │ └── index.vue
│ ├── sysError/
│ │ └── sysError.vue
│ ├── system/
│ │ └── system.vue
│ └── version/
│ └── version.vue
├── uno.config.js
├── vite.config.js
└── vitePlugin/
├── componentName/
│ └── index.js
└── secret/
└── index.js
SYMBOL INDEX (1568 symbols across 382 files)
FILE: server/api/v1/enter.go
type ApiGroup (line 10) | type ApiGroup struct
FILE: server/api/v1/example/enter.go
type ApiGroup (line 5) | type ApiGroup struct
FILE: server/api/v1/example/exa_attachment_category.go
type AttachmentCategoryApi (line 12) | type AttachmentCategoryApi struct
method GetCategoryList (line 21) | func (a *AttachmentCategoryApi) GetCategoryList(c *gin.Context) {
method AddCategory (line 39) | func (a *AttachmentCategoryApi) AddCategory(c *gin.Context) {
method DeleteCategory (line 64) | func (a *AttachmentCategoryApi) DeleteCategory(c *gin.Context) {
FILE: server/api/v1/example/exa_breakpoint_continue.go
method BreakpointContinue (line 29) | func (b *FileUploadAndDownloadApi) BreakpointContinue(c *gin.Context) {
method FindFile (line 89) | func (b *FileUploadAndDownloadApi) FindFile(c *gin.Context) {
method BreakpointContinueFinish (line 111) | func (b *FileUploadAndDownloadApi) BreakpointContinueFinish(c *gin.Conte...
method RemoveChunk (line 132) | func (b *FileUploadAndDownloadApi) RemoveChunk(c *gin.Context) {
FILE: server/api/v1/example/exa_customer.go
type CustomerApi (line 14) | type CustomerApi struct
method CreateExaCustomer (line 25) | func (e *CustomerApi) CreateExaCustomer(c *gin.Context) {
method DeleteExaCustomer (line 57) | func (e *CustomerApi) DeleteExaCustomer(c *gin.Context) {
method UpdateExaCustomer (line 87) | func (e *CustomerApi) UpdateExaCustomer(c *gin.Context) {
method GetExaCustomer (line 122) | func (e *CustomerApi) GetExaCustomer(c *gin.Context) {
method GetExaCustomerList (line 152) | func (e *CustomerApi) GetExaCustomerList(c *gin.Context) {
FILE: server/api/v1/example/exa_file_upload_download.go
type FileUploadAndDownloadApi (line 14) | type FileUploadAndDownloadApi struct
method UploadFile (line 25) | func (b *FileUploadAndDownloadApi) UploadFile(c *gin.Context) {
method EditFileName (line 45) | func (b *FileUploadAndDownloadApi) EditFileName(c *gin.Context) {
method DeleteFile (line 69) | func (b *FileUploadAndDownloadApi) DeleteFile(c *gin.Context) {
method GetFileList (line 93) | func (b *FileUploadAndDownloadApi) GetFileList(c *gin.Context) {
method ImportURL (line 122) | func (b *FileUploadAndDownloadApi) ImportURL(c *gin.Context) {
FILE: server/api/v1/system/auto_code_history.go
type AutoCodeHistoryApi (line 12) | type AutoCodeHistoryApi struct
method First (line 23) | func (a *AutoCodeHistoryApi) First(c *gin.Context) {
method Delete (line 47) | func (a *AutoCodeHistoryApi) Delete(c *gin.Context) {
method RollBack (line 72) | func (a *AutoCodeHistoryApi) RollBack(c *gin.Context) {
method GetList (line 96) | func (a *AutoCodeHistoryApi) GetList(c *gin.Context) {
FILE: server/api/v1/system/auto_code_mcp.go
method MCP (line 22) | func (a *AutoCodeTemplateApi) MCP(c *gin.Context) {
method MCPList (line 48) | func (a *AutoCodeTemplateApi) MCPList(c *gin.Context) {
method MCPTest (line 86) | func (a *AutoCodeTemplateApi) MCPTest(c *gin.Context) {
FILE: server/api/v1/system/auto_code_package.go
type AutoCodePackageApi (line 14) | type AutoCodePackageApi struct
method Create (line 25) | func (a *AutoCodePackageApi) Create(c *gin.Context) {
method Delete (line 54) | func (a *AutoCodePackageApi) Delete(c *gin.Context) {
method All (line 74) | func (a *AutoCodePackageApi) All(c *gin.Context) {
method Templates (line 92) | func (a *AutoCodePackageApi) Templates(c *gin.Context) {
FILE: server/api/v1/system/auto_code_plugin.go
type AutoCodePluginApi (line 17) | type AutoCodePluginApi struct
method Install (line 28) | func (a *AutoCodePluginApi) Install(c *gin.Context) {
method Packaged (line 67) | func (a *AutoCodePluginApi) Packaged(c *gin.Context) {
method InitMenu (line 86) | func (a *AutoCodePluginApi) InitMenu(c *gin.Context) {
method InitAPI (line 110) | func (a *AutoCodePluginApi) InitAPI(c *gin.Context) {
method InitDictionary (line 134) | func (a *AutoCodePluginApi) InitDictionary(c *gin.Context) {
method GetPluginList (line 157) | func (a *AutoCodePluginApi) GetPluginList(c *gin.Context) {
method Remove (line 208) | func (a *AutoCodePluginApi) Remove(c *gin.Context) {
FILE: server/api/v1/system/auto_code_template.go
type AutoCodeTemplateApi (line 12) | type AutoCodeTemplateApi struct
method Preview (line 23) | func (a *AutoCodeTemplateApi) Preview(c *gin.Context) {
method Create (line 59) | func (a *AutoCodeTemplateApi) Create(c *gin.Context) {
method AddFunc (line 94) | func (a *AutoCodeTemplateApi) AddFunc(c *gin.Context) {
FILE: server/api/v1/system/enter.go
type ApiGroup (line 5) | type ApiGroup struct
FILE: server/api/v1/system/sys_api.go
type SystemApiApi (line 16) | type SystemApiApi struct
method CreateApi (line 27) | func (s *SystemApiApi) CreateApi(c *gin.Context) {
method SyncApi (line 56) | func (s *SystemApiApi) SyncApi(c *gin.Context) {
method GetApiGroups (line 78) | func (s *SystemApiApi) GetApiGroups(c *gin.Context) {
method IgnoreApi (line 99) | func (s *SystemApiApi) IgnoreApi(c *gin.Context) {
method EnterSyncApi (line 123) | func (s *SystemApiApi) EnterSyncApi(c *gin.Context) {
method DeleteApi (line 148) | func (s *SystemApiApi) DeleteApi(c *gin.Context) {
method GetApiList (line 178) | func (s *SystemApiApi) GetApiList(c *gin.Context) {
method GetApiById (line 213) | func (s *SystemApiApi) GetApiById(c *gin.Context) {
method UpdateApi (line 243) | func (s *SystemApiApi) UpdateApi(c *gin.Context) {
method GetAllApis (line 272) | func (s *SystemApiApi) GetAllApis(c *gin.Context) {
method DeleteApisByIds (line 292) | func (s *SystemApiApi) DeleteApisByIds(c *gin.Context) {
method FreshCasbin (line 315) | func (s *SystemApiApi) FreshCasbin(c *gin.Context) {
method GetApiRoles (line 335) | func (s *SystemApiApi) GetApiRoles(c *gin.Context) {
method SetApiRoles (line 363) | func (s *SystemApiApi) SetApiRoles(c *gin.Context) {
FILE: server/api/v1/system/sys_api_token.go
type ApiTokenApi (line 12) | type ApiTokenApi struct
method CreateApiToken (line 15) | func (s *ApiTokenApi) CreateApiToken(c *gin.Context) {
method GetApiTokenList (line 45) | func (s *ApiTokenApi) GetApiTokenList(c *gin.Context) {
method DeleteApiToken (line 67) | func (s *ApiTokenApi) DeleteApiToken(c *gin.Context) {
FILE: server/api/v1/system/sys_authority.go
type AuthorityApi (line 15) | type AuthorityApi struct
method CreateAuthority (line 26) | func (a *AuthorityApi) CreateAuthority(c *gin.Context) {
method CopyAuthority (line 67) | func (a *AuthorityApi) CopyAuthority(c *gin.Context) {
method DeleteAuthority (line 103) | func (a *AuthorityApi) DeleteAuthority(c *gin.Context) {
method UpdateAuthority (line 133) | func (a *AuthorityApi) UpdateAuthority(c *gin.Context) {
method GetAuthorityList (line 163) | func (a *AuthorityApi) GetAuthorityList(c *gin.Context) {
method SetDataAuthority (line 183) | func (a *AuthorityApi) SetDataAuthority(c *gin.Context) {
method GetUsersByAuthority (line 214) | func (a *AuthorityApi) GetUsersByAuthority(c *gin.Context) {
method SetRoleUsers (line 241) | func (a *AuthorityApi) SetRoleUsers(c *gin.Context) {
FILE: server/api/v1/system/sys_authority_btn.go
type AuthorityBtnApi (line 11) | type AuthorityBtnApi struct
method GetAuthorityBtn (line 22) | func (a *AuthorityBtnApi) GetAuthorityBtn(c *gin.Context) {
method SetAuthorityBtn (line 47) | func (a *AuthorityBtnApi) SetAuthorityBtn(c *gin.Context) {
method CanRemoveAuthorityBtn (line 71) | func (a *AuthorityBtnApi) CanRemoveAuthorityBtn(c *gin.Context) {
FILE: server/api/v1/system/sys_auto_code.go
type AutoCodeApi (line 12) | type AutoCodeApi struct
method GetDB (line 22) | func (autoApi *AutoCodeApi) GetDB(c *gin.Context) {
method GetTables (line 50) | func (autoApi *AutoCodeApi) GetTables(c *gin.Context) {
method GetColumn (line 81) | func (autoApi *AutoCodeApi) GetColumn(c *gin.Context) {
method LLMAuto (line 104) | func (autoApi *AutoCodeApi) LLMAuto(c *gin.Context) {
FILE: server/api/v1/system/sys_captcha.go
type BaseApi (line 18) | type BaseApi struct
method Captcha (line 28) | func (b *BaseApi) Captcha(c *gin.Context) {
function interfaceToInt (line 62) | func interfaceToInt(v interface{}) (i int) {
FILE: server/api/v1/system/sys_casbin.go
type CasbinApi (line 13) | type CasbinApi struct
method UpdateCasbin (line 24) | func (cas *CasbinApi) UpdateCasbin(c *gin.Context) {
method GetPolicyPathByAuthorityId (line 55) | func (cas *CasbinApi) GetPolicyPathByAuthorityId(c *gin.Context) {
FILE: server/api/v1/system/sys_dictionary.go
type DictionaryApi (line 12) | type DictionaryApi struct
method CreateSysDictionary (line 23) | func (s *DictionaryApi) CreateSysDictionary(c *gin.Context) {
method DeleteSysDictionary (line 48) | func (s *DictionaryApi) DeleteSysDictionary(c *gin.Context) {
method UpdateSysDictionary (line 73) | func (s *DictionaryApi) UpdateSysDictionary(c *gin.Context) {
method FindSysDictionary (line 98) | func (s *DictionaryApi) FindSysDictionary(c *gin.Context) {
method GetSysDictionaryList (line 123) | func (s *DictionaryApi) GetSysDictionaryList(c *gin.Context) {
method ExportSysDictionary (line 148) | func (s *DictionaryApi) ExportSysDictionary(c *gin.Context) {
method ImportSysDictionary (line 177) | func (s *DictionaryApi) ImportSysDictionary(c *gin.Context) {
FILE: server/api/v1/system/sys_dictionary_detail.go
type DictionaryDetailApi (line 15) | type DictionaryDetailApi struct
method CreateSysDictionaryDetail (line 26) | func (s *DictionaryDetailApi) CreateSysDictionaryDetail(c *gin.Context) {
method DeleteSysDictionaryDetail (line 51) | func (s *DictionaryDetailApi) DeleteSysDictionaryDetail(c *gin.Context) {
method UpdateSysDictionaryDetail (line 76) | func (s *DictionaryDetailApi) UpdateSysDictionaryDetail(c *gin.Context) {
method FindSysDictionaryDetail (line 101) | func (s *DictionaryDetailApi) FindSysDictionaryDetail(c *gin.Context) {
method GetSysDictionaryDetailList (line 131) | func (s *DictionaryDetailApi) GetSysDictionaryDetailList(c *gin.Contex...
method GetDictionaryTreeList (line 161) | func (s *DictionaryDetailApi) GetDictionaryTreeList(c *gin.Context) {
method GetDictionaryTreeListByType (line 194) | func (s *DictionaryDetailApi) GetDictionaryTreeListByType(c *gin.Conte...
method GetDictionaryDetailsByParent (line 219) | func (s *DictionaryDetailApi) GetDictionaryDetailsByParent(c *gin.Cont...
method GetDictionaryPath (line 245) | func (s *DictionaryDetailApi) GetDictionaryPath(c *gin.Context) {
FILE: server/api/v1/system/sys_error.go
type SysErrorApi (line 12) | type SysErrorApi struct
method CreateSysError (line 23) | func (sysErrorApi *SysErrorApi) CreateSysError(c *gin.Context) {
method DeleteSysError (line 51) | func (sysErrorApi *SysErrorApi) DeleteSysError(c *gin.Context) {
method DeleteSysErrorByIds (line 73) | func (sysErrorApi *SysErrorApi) DeleteSysErrorByIds(c *gin.Context) {
method UpdateSysError (line 96) | func (sysErrorApi *SysErrorApi) UpdateSysError(c *gin.Context) {
method FindSysError (line 124) | func (sysErrorApi *SysErrorApi) FindSysError(c *gin.Context) {
method GetSysErrorList (line 147) | func (sysErrorApi *SysErrorApi) GetSysErrorList(c *gin.Context) {
method GetSysErrorSolution (line 180) | func (sysErrorApi *SysErrorApi) GetSysErrorSolution(c *gin.Context) {
FILE: server/api/v1/system/sys_export_template.go
function cleanupExpiredTokens (line 29) | func cleanupExpiredTokens() {
function init (line 44) | func init() {
type SysExportTemplateApi (line 48) | type SysExportTemplateApi struct
method PreviewSQL (line 63) | func (sysExportTemplateApi *SysExportTemplateApi) PreviewSQL(c *gin.Co...
method CreateSysExportTemplate (line 90) | func (sysExportTemplateApi *SysExportTemplateApi) CreateSysExportTempl...
method DeleteSysExportTemplate (line 121) | func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTempl...
method DeleteSysExportTemplateByIds (line 145) | func (sysExportTemplateApi *SysExportTemplateApi) DeleteSysExportTempl...
method UpdateSysExportTemplate (line 169) | func (sysExportTemplateApi *SysExportTemplateApi) UpdateSysExportTempl...
method FindSysExportTemplate (line 200) | func (sysExportTemplateApi *SysExportTemplateApi) FindSysExportTemplat...
method GetSysExportTemplateList (line 224) | func (sysExportTemplateApi *SysExportTemplateApi) GetSysExportTemplate...
method ExportExcel (line 251) | func (sysExportTemplateApi *SysExportTemplateApi) ExportExcel(c *gin.C...
method ExportExcelByToken (line 287) | func (sysExportTemplateApi *SysExportTemplateApi) ExportExcelByToken(c...
method ExportTemplate (line 342) | func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplate(c *gi...
method ExportTemplateByToken (line 376) | func (sysExportTemplateApi *SysExportTemplateApi) ExportTemplateByToke...
method ImportExcel (line 438) | func (sysExportTemplateApi *SysExportTemplateApi) ImportExcel(c *gin.C...
FILE: server/api/v1/system/sys_initdb.go
type DBApi (line 12) | type DBApi struct
method InitDB (line 21) | func (i *DBApi) InitDB(c *gin.Context) {
method CheckDB (line 47) | func (i *DBApi) CheckDB(c *gin.Context) {
FILE: server/api/v1/system/sys_jwt_blacklist.go
type JwtApi (line 12) | type JwtApi struct
method JsonInBlacklist (line 22) | func (j *JwtApi) JsonInBlacklist(c *gin.Context) {
FILE: server/api/v1/system/sys_login_log.go
type LoginLogApi (line 13) | type LoginLogApi struct
method DeleteLoginLog (line 15) | func (s *LoginLogApi) DeleteLoginLog(c *gin.Context) {
method DeleteLoginLogByIds (line 31) | func (s *LoginLogApi) DeleteLoginLogByIds(c *gin.Context) {
method FindLoginLog (line 47) | func (s *LoginLogApi) FindLoginLog(c *gin.Context) {
method GetLoginLogList (line 63) | func (s *LoginLogApi) GetLoginLogList(c *gin.Context) {
FILE: server/api/v1/system/sys_menu.go
type AuthorityMenuApi (line 16) | type AuthorityMenuApi struct
method GetMenu (line 26) | func (a *AuthorityMenuApi) GetMenu(c *gin.Context) {
method GetBaseMenuTree (line 47) | func (a *AuthorityMenuApi) GetBaseMenuTree(c *gin.Context) {
method AddMenuAuthority (line 67) | func (a *AuthorityMenuApi) AddMenuAuthority(c *gin.Context) {
method GetMenuAuthority (line 96) | func (a *AuthorityMenuApi) GetMenuAuthority(c *gin.Context) {
method AddBaseMenu (line 126) | func (a *AuthorityMenuApi) AddBaseMenu(c *gin.Context) {
method DeleteBaseMenu (line 161) | func (a *AuthorityMenuApi) DeleteBaseMenu(c *gin.Context) {
method UpdateBaseMenu (line 191) | func (a *AuthorityMenuApi) UpdateBaseMenu(c *gin.Context) {
method GetBaseMenuById (line 226) | func (a *AuthorityMenuApi) GetBaseMenuById(c *gin.Context) {
method GetMenuRoles (line 256) | func (a *AuthorityMenuApi) GetMenuRoles(c *gin.Context) {
method SetMenuRoles (line 299) | func (a *AuthorityMenuApi) SetMenuRoles(c *gin.Context) {
method GetMenuList (line 326) | func (a *AuthorityMenuApi) GetMenuList(c *gin.Context) {
FILE: server/api/v1/system/sys_operation_record.go
type OperationRecordApi (line 14) | type OperationRecordApi struct
method DeleteSysOperationRecord (line 25) | func (s *OperationRecordApi) DeleteSysOperationRecord(c *gin.Context) {
method DeleteSysOperationRecordByIds (line 50) | func (s *OperationRecordApi) DeleteSysOperationRecordByIds(c *gin.Cont...
method FindSysOperationRecord (line 75) | func (s *OperationRecordApi) FindSysOperationRecord(c *gin.Context) {
method GetSysOperationRecordList (line 105) | func (s *OperationRecordApi) GetSysOperationRecordList(c *gin.Context) {
FILE: server/api/v1/system/sys_params.go
type SysParamsApi (line 12) | type SysParamsApi struct
method CreateSysParams (line 23) | func (sysParamsApi *SysParamsApi) CreateSysParams(c *gin.Context) {
method DeleteSysParams (line 48) | func (sysParamsApi *SysParamsApi) DeleteSysParams(c *gin.Context) {
method DeleteSysParamsByIds (line 67) | func (sysParamsApi *SysParamsApi) DeleteSysParamsByIds(c *gin.Context) {
method UpdateSysParams (line 87) | func (sysParamsApi *SysParamsApi) UpdateSysParams(c *gin.Context) {
method FindSysParams (line 112) | func (sysParamsApi *SysParamsApi) FindSysParams(c *gin.Context) {
method GetSysParamsList (line 132) | func (sysParamsApi *SysParamsApi) GetSysParamsList(c *gin.Context) {
method GetSysParam (line 162) | func (sysParamsApi *SysParamsApi) GetSysParam(c *gin.Context) {
FILE: server/api/v1/system/sys_skills.go
type SkillsApi (line 13) | type SkillsApi struct
method GetTools (line 15) | func (s *SkillsApi) GetTools(c *gin.Context) {
method GetSkillList (line 25) | func (s *SkillsApi) GetSkillList(c *gin.Context) {
method GetSkillDetail (line 37) | func (s *SkillsApi) GetSkillDetail(c *gin.Context) {
method SaveSkill (line 49) | func (s *SkillsApi) SaveSkill(c *gin.Context) {
method DeleteSkill (line 60) | func (s *SkillsApi) DeleteSkill(c *gin.Context) {
method CreateScript (line 71) | func (s *SkillsApi) CreateScript(c *gin.Context) {
method GetScript (line 83) | func (s *SkillsApi) GetScript(c *gin.Context) {
method SaveScript (line 95) | func (s *SkillsApi) SaveScript(c *gin.Context) {
method CreateResource (line 106) | func (s *SkillsApi) CreateResource(c *gin.Context) {
method GetResource (line 118) | func (s *SkillsApi) GetResource(c *gin.Context) {
method SaveResource (line 130) | func (s *SkillsApi) SaveResource(c *gin.Context) {
method CreateReference (line 141) | func (s *SkillsApi) CreateReference(c *gin.Context) {
method GetReference (line 153) | func (s *SkillsApi) GetReference(c *gin.Context) {
method SaveReference (line 165) | func (s *SkillsApi) SaveReference(c *gin.Context) {
method CreateTemplate (line 176) | func (s *SkillsApi) CreateTemplate(c *gin.Context) {
method GetTemplate (line 188) | func (s *SkillsApi) GetTemplate(c *gin.Context) {
method SaveTemplate (line 200) | func (s *SkillsApi) SaveTemplate(c *gin.Context) {
method GetGlobalConstraint (line 211) | func (s *SkillsApi) GetGlobalConstraint(c *gin.Context) {
method SaveGlobalConstraint (line 223) | func (s *SkillsApi) SaveGlobalConstraint(c *gin.Context) {
method PackageSkill (line 234) | func (s *SkillsApi) PackageSkill(c *gin.Context) {
method DownloadOnlineSkill (line 250) | func (s *SkillsApi) DownloadOnlineSkill(c *gin.Context) {
FILE: server/api/v1/system/sys_system.go
type SystemApi (line 13) | type SystemApi struct
method GetSystemConfig (line 22) | func (s *SystemApi) GetSystemConfig(c *gin.Context) {
method SetSystemConfig (line 40) | func (s *SystemApi) SetSystemConfig(c *gin.Context) {
method ReloadSystem (line 63) | func (s *SystemApi) ReloadSystem(c *gin.Context) {
method GetServerInfo (line 81) | func (s *SystemApi) GetServerInfo(c *gin.Context) {
FILE: server/api/v1/system/sys_user.go
method Login (line 27) | func (b *BaseApi) Login(c *gin.Context) {
method TokenNext (line 102) | func (b *BaseApi) TokenNext(c *gin.Context, user system.SysUser) {
method Register (line 170) | func (b *BaseApi) Register(c *gin.Context) {
method ChangePassword (line 206) | func (b *BaseApi) ChangePassword(c *gin.Context) {
method GetUserList (line 238) | func (b *BaseApi) GetUserList(c *gin.Context) {
method SetUserAuthority (line 273) | func (b *BaseApi) SetUserAuthority(c *gin.Context) {
method SetUserAuthorities (line 314) | func (b *BaseApi) SetUserAuthorities(c *gin.Context) {
method DeleteUser (line 340) | func (b *BaseApi) DeleteUser(c *gin.Context) {
method SetUserInfo (line 375) | func (b *BaseApi) SetUserInfo(c *gin.Context) {
method SetSelfInfo (line 423) | func (b *BaseApi) SetSelfInfo(c *gin.Context) {
method SetSelfSetting (line 458) | func (b *BaseApi) SetSelfSetting(c *gin.Context) {
method GetUserInfo (line 483) | func (b *BaseApi) GetUserInfo(c *gin.Context) {
method ResetPassword (line 502) | func (b *BaseApi) ResetPassword(c *gin.Context) {
FILE: server/api/v1/system/sys_version.go
type SysVersionApi (line 21) | type SysVersionApi struct
method DeleteSysVersion (line 118) | func (sysVersionApi *SysVersionApi) DeleteSysVersion(c *gin.Context) {
method DeleteSysVersionByIds (line 140) | func (sysVersionApi *SysVersionApi) DeleteSysVersionByIds(c *gin.Conte...
method FindSysVersion (line 163) | func (sysVersionApi *SysVersionApi) FindSysVersion(c *gin.Context) {
method GetSysVersionList (line 186) | func (sysVersionApi *SysVersionApi) GetSysVersionList(c *gin.Context) {
method GetSysVersionPublic (line 217) | func (sysVersionApi *SysVersionApi) GetSysVersionPublic(c *gin.Context) {
method ExportVersion (line 238) | func (sysVersionApi *SysVersionApi) ExportVersion(c *gin.Context) {
method DownloadVersionJson (line 372) | func (sysVersionApi *SysVersionApi) DownloadVersionJson(c *gin.Context) {
method ImportVersion (line 426) | func (sysVersionApi *SysVersionApi) ImportVersion(c *gin.Context) {
function buildMenuTree (line 24) | func buildMenuTree(menus []system.SysBaseMenu) []system.SysBaseMenu {
function convertMenuToStruct (line 50) | func convertMenuToStruct(menu system.SysBaseMenu, menuMap map[uint]*syst...
FILE: server/config/auto_code.go
type Autocode (line 8) | type Autocode struct
method WebRoot (line 16) | func (a *Autocode) WebRoot() string {
FILE: server/config/captcha.go
type Captcha (line 3) | type Captcha struct
FILE: server/config/config.go
type Server (line 3) | type Server struct
FILE: server/config/cors.go
type CORS (line 3) | type CORS struct
type CORSWhitelist (line 8) | type CORSWhitelist struct
FILE: server/config/db_list.go
type DsnProvider (line 9) | type DsnProvider interface
type GeneralDB (line 17) | type GeneralDB struct
method LogLevel (line 33) | func (c GeneralDB) LogLevel() logger.LogLevel {
type SpecializedDB (line 48) | type SpecializedDB struct
FILE: server/config/disk.go
type Disk (line 3) | type Disk struct
type DiskList (line 7) | type DiskList struct
FILE: server/config/email.go
type Email (line 3) | type Email struct
FILE: server/config/excel.go
type Excel (line 3) | type Excel struct
FILE: server/config/gorm_mssql.go
type Mssql (line 3) | type Mssql struct
method Dsn (line 8) | func (m *Mssql) Dsn() string {
FILE: server/config/gorm_mysql.go
type Mysql (line 3) | type Mysql struct
method Dsn (line 7) | func (m *Mysql) Dsn() string {
FILE: server/config/gorm_oracle.go
type Oracle (line 9) | type Oracle struct
method Dsn (line 13) | func (m *Oracle) Dsn() string {
FILE: server/config/gorm_pgsql.go
type Pgsql (line 3) | type Pgsql struct
method Dsn (line 9) | func (p *Pgsql) Dsn() string {
method LinkDsn (line 15) | func (p *Pgsql) LinkDsn(dbname string) string {
FILE: server/config/gorm_sqlite.go
type Sqlite (line 7) | type Sqlite struct
method Dsn (line 11) | func (s *Sqlite) Dsn() string {
FILE: server/config/jwt.go
type JWT (line 3) | type JWT struct
FILE: server/config/mcp.go
type MCP (line 3) | type MCP struct
FILE: server/config/mongo.go
type Mongo (line 8) | type Mongo struct
method Uri (line 29) | func (x *Mongo) Uri() string {
type MongoHost (line 23) | type MongoHost struct
FILE: server/config/oss_aliyun.go
type AliyunOSS (line 3) | type AliyunOSS struct
FILE: server/config/oss_aws.go
type AwsS3 (line 3) | type AwsS3 struct
FILE: server/config/oss_cloudflare.go
type CloudflareR2 (line 3) | type CloudflareR2 struct
FILE: server/config/oss_huawei.go
type HuaWeiObs (line 3) | type HuaWeiObs struct
FILE: server/config/oss_local.go
type Local (line 3) | type Local struct
FILE: server/config/oss_minio.go
type Minio (line 3) | type Minio struct
FILE: server/config/oss_qiniu.go
type Qiniu (line 3) | type Qiniu struct
FILE: server/config/oss_tencent.go
type TencentCOS (line 3) | type TencentCOS struct
FILE: server/config/redis.go
type Redis (line 3) | type Redis struct
FILE: server/config/system.go
type System (line 3) | type System struct
FILE: server/config/zap.go
type Zap (line 8) | type Zap struct
method Levels (line 21) | func (c *Zap) Levels() []zapcore.Level {
method Encoder (line 33) | func (c *Zap) Encoder() zapcore.Encoder {
method LevelEncoder (line 58) | func (c *Zap) LevelEncoder() zapcore.LevelEncoder {
FILE: server/core/internal/constant.go
constant ConfigEnv (line 4) | ConfigEnv = "GVA_CONFIG"
constant ConfigDefaultFile (line 5) | ConfigDefaultFile = "config.yaml"
constant ConfigTestFile (line 6) | ConfigTestFile = "config.test.yaml"
constant ConfigDebugFile (line 7) | ConfigDebugFile = "config.debug.yaml"
constant ConfigReleaseFile (line 8) | ConfigReleaseFile = "config.release.yaml"
FILE: server/core/internal/cutter.go
type Cutter (line 13) | type Cutter struct
method Write (line 58) | func (c *Cutter) Write(bytes []byte) (n int, err error) {
method Sync (line 97) | func (c *Cutter) Sync() error {
type CutterOption (line 23) | type CutterOption
function CutterWithLayout (line 26) | func CutterWithLayout(layout string) CutterOption {
function CutterWithFormats (line 33) | func CutterWithFormats(format ...string) CutterOption {
function NewCutter (line 41) | func NewCutter(director string, level string, retentionDay int, options ...
function removeNDaysFolders (line 108) | func removeNDaysFolders(dir string, days int) error {
FILE: server/core/internal/zap_core.go
type ZapCore (line 18) | type ZapCore struct
method WriteSyncer (line 33) | func (z *ZapCore) WriteSyncer(formats ...string) zapcore.WriteSyncer {
method Enabled (line 48) | func (z *ZapCore) Enabled(level zapcore.Level) bool {
method With (line 52) | func (z *ZapCore) With(fields []zapcore.Field) zapcore.Core {
method Check (line 56) | func (z *ZapCore) Check(entry zapcore.Entry, check *zapcore.CheckedEnt...
method Write (line 63) | func (z *ZapCore) Write(entry zapcore.Entry, fields []zapcore.Field) e...
method Sync (line 131) | func (z *ZapCore) Sync() error {
function NewZapCore (line 23) | func NewZapCore(level zapcore.Level) *ZapCore {
FILE: server/core/server.go
function RunServer (line 12) | func RunServer() {
FILE: server/core/server_run.go
type server (line 16) | type server interface
function initServer (line 22) | func initServer(address string, router *gin.Engine, readTimeout, writeTi...
FILE: server/core/viper.go
function Viper (line 17) | func Viper() *viper.Viper {
function getConfigPath (line 45) | func getConfigPath() (config string) {
FILE: server/core/zap.go
function Zap (line 15) | func Zap() (logger *zap.Logger) {
FILE: server/docs/docs.go
constant docTemplate (line 10) | docTemplate = `{
function init (line 9312) | func init() {
FILE: server/global/global.go
function GetGlobalDBByDBName (line 45) | func GetGlobalDBByDBName(dbname string) *gorm.DB {
function MustGetGlobalDBByDBName (line 52) | func MustGetGlobalDBByDBName(dbname string) *gorm.DB {
function GetRedis (line 62) | func GetRedis(name string) redis.UniversalClient {
FILE: server/global/model.go
type GVA_MODEL (line 9) | type GVA_MODEL struct
FILE: server/global/version.go
constant Version (line 7) | Version = "v2.9.0"
constant AppName (line 9) | AppName = "Gin-Vue-Admin"
constant Description (line 11) | Description = "使用gin+vue进行极速开发的全栈开发基础平台"
FILE: server/initialize/db_list.go
constant sys (line 9) | sys = "system"
function DBList (line 11) | func DBList() {
FILE: server/initialize/ensure_tables.go
constant initOrderEnsureTables (line 13) | initOrderEnsureTables = system.InitOrderExternal - 1
type ensureTables (line 15) | type ensureTables struct
method InitializerName (line 22) | func (e *ensureTables) InitializerName() string {
method InitializeData (line 25) | func (e *ensureTables) InitializeData(ctx context.Context) (next conte...
method DataInserted (line 29) | func (e *ensureTables) DataInserted(ctx context.Context) bool {
method MigrateTable (line 33) | func (e *ensureTables) MigrateTable(ctx context.Context) (context.Cont...
method TableCreated (line 78) | func (e *ensureTables) TableCreated(ctx context.Context) bool {
function init (line 18) | func init() {
FILE: server/initialize/gorm.go
function Gorm (line 14) | func Gorm() *gorm.DB {
function RegisterTables (line 37) | func RegisterTables() {
FILE: server/initialize/gorm_biz.go
function bizModel (line 7) | func bizModel() error {
FILE: server/initialize/gorm_mssql.go
function GormMssql (line 22) | func GormMssql() *gorm.DB {
function GormMssqlByConfig (line 45) | func GormMssqlByConfig(m config.Mssql) *gorm.DB {
FILE: server/initialize/gorm_mysql.go
function GormMysql (line 16) | func GormMysql() *gorm.DB {
function GormMysqlByConfig (line 22) | func GormMysqlByConfig(m config.Mysql) *gorm.DB {
function initMysqlDatabase (line 27) | func initMysqlDatabase(m config.Mysql) *gorm.DB {
FILE: server/initialize/gorm_oracle.go
function GormOracle (line 12) | func GormOracle() *gorm.DB {
function GormOracleByConfig (line 18) | func GormOracleByConfig(m config.Oracle) *gorm.DB {
function initOracleDatabase (line 23) | func initOracleDatabase(m config.Oracle) *gorm.DB {
FILE: server/initialize/gorm_pgsql.go
function GormPgSql (line 14) | func GormPgSql() *gorm.DB {
function GormPgSqlByConfig (line 20) | func GormPgSqlByConfig(p config.Pgsql) *gorm.DB {
function initPgSqlDatabase (line 25) | func initPgSqlDatabase(p config.Pgsql) *gorm.DB {
FILE: server/initialize/gorm_sqlite.go
function GormSqlite (line 12) | func GormSqlite() *gorm.DB {
function GormSqliteByConfig (line 18) | func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
function initSqliteDatabase (line 23) | func initSqliteDatabase(s config.Sqlite) *gorm.DB {
FILE: server/initialize/init.go
function SetupHandlers (line 10) | func SetupHandlers() {
FILE: server/initialize/internal/gorm.go
type _gorm (line 14) | type _gorm struct
method Config (line 18) | func (g *_gorm) Config(general config.GeneralDB) *gorm.Config {
FILE: server/initialize/internal/gorm_logger_writer.go
type Writer (line 10) | type Writer struct
method Printf (line 20) | func (c *Writer) Printf(message string, data ...any) {
function NewWriter (line 15) | func NewWriter(config config.GeneralDB) *Writer {
FILE: server/initialize/internal/mongo.go
type mongo (line 14) | type mongo struct
method GetClientOptions (line 16) | func (m *mongo) GetClientOptions() []options.ClientOptions {
FILE: server/initialize/mcp.go
function McpRun (line 9) | func McpRun() *server.SSEServer {
FILE: server/initialize/mongo.go
type mongo (line 21) | type mongo struct
method Indexes (line 30) | func (m *mongo) Indexes(ctx context.Context) error {
method Initialization (line 42) | func (m *mongo) Initialization() error {
method CreateIndexes (line 77) | func (m *mongo) CreateIndexes(ctx context.Context, name string, indexe...
type Index (line 22) | type Index struct
FILE: server/initialize/other.go
function OtherInit (line 13) | func OtherInit() {
FILE: server/initialize/plugin.go
function InstallPlugin (line 8) | func InstallPlugin(PrivateGroup *gin.RouterGroup, PublicRouter *gin.Rout...
FILE: server/initialize/plugin_biz_v1.go
function PluginInit (line 12) | func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
function bizPluginV1 (line 21) | func bizPluginV1(group ...*gin.RouterGroup) {
FILE: server/initialize/plugin_biz_v2.go
function PluginInitV2 (line 9) | func PluginInitV2(group *gin.Engine, plugins ...plugin.Plugin) {
function bizPluginV2 (line 14) | func bizPluginV2(engine *gin.Engine) {
FILE: server/initialize/redis.go
function initRedisClient (line 13) | func initRedisClient(redisCfg config.Redis) (redis.UniversalClient, erro...
function Redis (line 39) | func Redis() {
function RedisList (line 47) | func RedisList() {
FILE: server/initialize/register_init.go
function init (line 8) | func init() {
FILE: server/initialize/reload.go
function Reload (line 9) | func Reload() error {
FILE: server/initialize/router.go
type justFilesFilesystem (line 16) | type justFilesFilesystem struct
method Open (line 20) | func (fs justFilesFilesystem) Open(name string) (http.File, error) {
function Routers (line 36) | func Routers() *gin.Engine {
FILE: server/initialize/router_biz.go
function holder (line 9) | func holder(routers ...*gin.RouterGroup) {
function initBizRouter (line 14) | func initBizRouter(routers ...*gin.RouterGroup) {
FILE: server/initialize/timer.go
function Timer (line 12) | func Timer() {
FILE: server/initialize/validator.go
function init (line 5) | func init() {
FILE: server/main.go
function main (line 30) | func main() {
function initializeSystem (line 39) | func initializeSystem() {
FILE: server/mcp/api_creator.go
function init (line 17) | func init() {
type ApiCreateRequest (line 22) | type ApiCreateRequest struct
type ApiCreateResponse (line 30) | type ApiCreateResponse struct
type ApiCreator (line 39) | type ApiCreator struct
method New (line 42) | func (a *ApiCreator) New() mcp.Tool {
method Handle (line 72) | func (a *ApiCreator) Handle(ctx context.Context, request mcp.CallToolR...
FILE: server/mcp/api_lister.go
function init (line 15) | func init() {
type ApiInfo (line 21) | type ApiInfo struct
type ApiListResponse (line 31) | type ApiListResponse struct
type ApiLister (line 40) | type ApiLister struct
method New (line 43) | func (a *ApiLister) New() mcp.Tool {
method Handle (line 62) | func (a *ApiLister) Handle(_ context.Context, _ mcp.CallToolRequest) (...
method getDatabaseApis (line 132) | func (a *ApiLister) getDatabaseApis() ([]ApiInfo, error) {
method getGinApis (line 156) | func (a *ApiLister) getGinApis() ([]ApiInfo, error) {
FILE: server/mcp/client/client.go
function NewClient (line 10) | func NewClient(baseUrl, name, version, serverName string) (*mcpClient.Cl...
FILE: server/mcp/client/client_test.go
function TestMcpClientConnection (line 11) | func TestMcpClientConnection(t *testing.T) {
function TestTools (line 19) | func TestTools(t *testing.T) {
function TestGetTools (line 93) | func TestGetTools(t *testing.T) {
FILE: server/mcp/dictionary_generator.go
function init (line 17) | func init() {
type DictionaryOptionsGenerator (line 22) | type DictionaryOptionsGenerator struct
method New (line 49) | func (d *DictionaryOptionsGenerator) New() mcp.Tool {
method Handle (line 74) | func (d *DictionaryOptionsGenerator) Handle(ctx context.Context, reque...
method createDictionaryWithOptions (line 138) | func (d *DictionaryOptionsGenerator) createDictionaryWithOptions(ctx c...
method checkDictionaryExists (line 211) | func (d *DictionaryOptionsGenerator) checkDictionaryExists(dictType st...
method generateDictionaryName (line 224) | func (d *DictionaryOptionsGenerator) generateDictionaryName(dictType, ...
type DictionaryOption (line 25) | type DictionaryOption struct
type DictionaryGenerateRequest (line 32) | type DictionaryGenerateRequest struct
type DictionaryGenerateResponse (line 41) | type DictionaryGenerateResponse struct
FILE: server/mcp/dictionary_query.go
function init (line 17) | func init() {
type DictionaryPre (line 21) | type DictionaryPre struct
type DictionaryInfo (line 27) | type DictionaryInfo struct
type DictionaryDetailInfo (line 37) | type DictionaryDetailInfo struct
type DictionaryQueryResponse (line 47) | type DictionaryQueryResponse struct
type DictionaryQuery (line 55) | type DictionaryQuery struct
method New (line 58) | func (d *DictionaryQuery) New() mcp.Tool {
method Handle (line 74) | func (d *DictionaryQuery) Handle(ctx context.Context, request mcp.Call...
FILE: server/mcp/enter.go
type McpTool (line 10) | type McpTool interface
function RegisterTool (line 21) | func RegisterTool(tool McpTool) {
function RegisterAllTools (line 27) | func RegisterAllTools(mcpServer *server.MCPServer) {
FILE: server/mcp/gva_analyze.go
function init (line 18) | func init() {
type GVAAnalyzer (line 23) | type GVAAnalyzer struct
method New (line 76) | func (g *GVAAnalyzer) New() mcp.Tool {
method Handle (line 87) | func (g *GVAAnalyzer) Handle(ctx context.Context, request mcp.CallTool...
method performAnalysis (line 119) | func (g *GVAAnalyzer) performAnalysis(ctx context.Context, req Analyze...
method isPackageFolderEmpty (line 270) | func (g *GVAAnalyzer) isPackageFolderEmpty(packageName, template strin...
method hasGoFilesRecursive (line 290) | func (g *GVAAnalyzer) hasGoFilesRecursive(dirPath string) (bool, error) {
method removeEmptyPackageFolder (line 321) | func (g *GVAAnalyzer) removeEmptyPackageFolder(packageName, template s...
method removeDirectoryIfExists (line 345) | func (g *GVAAnalyzer) removeDirectoryIfExists(dirPath string) error {
method cleanupRelatedApiAndMenus (line 365) | func (g *GVAAnalyzer) cleanupRelatedApiAndMenus(historyIDs []uint) err...
method scanPredesignedModules (line 382) | func (g *GVAAnalyzer) scanPredesignedModules() ([]PredesignedModuleInf...
method scanPluginModules (line 411) | func (g *GVAAnalyzer) scanPluginModules(pluginDir string) ([]Predesign...
method scanModelModules (line 446) | func (g *GVAAnalyzer) scanModelModules(modelDir string) ([]Predesigned...
method scanModulesInDirectory (line 477) | func (g *GVAAnalyzer) scanModulesInDirectory(dir, packageName, templat...
type AnalyzeRequest (line 26) | type AnalyzeRequest struct
type AnalyzeResponse (line 31) | type AnalyzeResponse struct
type ModuleInfo (line 39) | type ModuleInfo struct
type PackageInfo (line 50) | type PackageInfo struct
type PredesignedModuleInfo (line 60) | type PredesignedModuleInfo struct
type CleanupInfo (line 69) | type CleanupInfo struct
FILE: server/mcp/gva_execute.go
function init (line 21) | func init() {
type GVAExecutor (line 26) | type GVAExecutor struct
method New (line 59) | func (g *GVAExecutor) New() mcp.Tool {
method Handle (line 222) | func (g *GVAExecutor) Handle(ctx context.Context, request mcp.CallTool...
method validateExecutionPlan (line 296) | func (g *GVAExecutor) validateExecutionPlan(plan *ExecutionPlan) error {
method executeCreation (line 467) | func (g *GVAExecutor) executeCreation(ctx context.Context, plan *Execu...
method buildDirectoryStructure (line 547) | func (g *GVAExecutor) buildDirectoryStructure(plan *ExecutionPlan) map...
method collectExpectedFilePaths (line 665) | func (g *GVAExecutor) collectExpectedFilePaths(plan *ExecutionPlan) []...
method checkDictionaryExists (line 710) | func (g *GVAExecutor) checkDictionaryExists(dictType string) (bool, er...
method createDictionariesFromInfo (line 725) | func (g *GVAExecutor) createDictionariesFromInfo(ctx context.Context, ...
type ExecuteRequest (line 29) | type ExecuteRequest struct
type ExecuteResponse (line 35) | type ExecuteResponse struct
type ExecutionPlan (line 46) | type ExecutionPlan struct
FILE: server/mcp/gva_review.go
type GVAReviewer (line 14) | type GVAReviewer struct
method New (line 36) | func (g *GVAReviewer) New() mcp.Tool {
method Handle (line 81) | func (g *GVAReviewer) Handle(ctx context.Context, request mcp.CallTool...
method generateAdjustmentPrompt (line 143) | func (g *GVAReviewer) generateAdjustmentPrompt(userRequirement string,...
function init (line 17) | func init() {
type ReviewRequest (line 22) | type ReviewRequest struct
type ReviewResponse (line 28) | type ReviewResponse struct
FILE: server/mcp/menu_creator.go
function init (line 17) | func init() {
type MenuCreateRequest (line 22) | type MenuCreateRequest struct
type MenuParameterRequest (line 40) | type MenuParameterRequest struct
type MenuButtonRequest (line 47) | type MenuButtonRequest struct
type MenuCreateResponse (line 53) | type MenuCreateResponse struct
type MenuCreator (line 62) | type MenuCreator struct
method New (line 65) | func (m *MenuCreator) New() mcp.Tool {
method Handle (line 125) | func (m *MenuCreator) Handle(ctx context.Context, request mcp.CallTool...
FILE: server/mcp/menu_lister.go
function init (line 15) | func init() {
type MenuListResponse (line 21) | type MenuListResponse struct
type MenuLister (line 30) | type MenuLister struct
method New (line 33) | func (m *MenuLister) New() mcp.Tool {
method Handle (line 56) | func (m *MenuLister) Handle(_ context.Context, _ mcp.CallToolRequest) ...
method getAllMenus (line 107) | func (m *MenuLister) getAllMenus() ([]system.SysBaseMenu, error) {
FILE: server/mcp/requirement_analyzer.go
function init (line 12) | func init() {
type RequirementAnalyzer (line 16) | type RequirementAnalyzer struct
method New (line 29) | func (t *RequirementAnalyzer) New() mcp.Tool {
method Handle (line 69) | func (t *RequirementAnalyzer) Handle(ctx context.Context, request mcp....
method analyzeRequirement (line 95) | func (t *RequirementAnalyzer) analyzeRequirement(userRequirement strin...
method generateAIPrompt (line 105) | func (t *RequirementAnalyzer) generateAIPrompt(userRequirement string)...
type RequirementAnalysisRequest (line 19) | type RequirementAnalysisRequest struct
type RequirementAnalysisResponse (line 24) | type RequirementAnalysisResponse struct
FILE: server/middleware/casbin_rbac.go
function CasbinHandler (line 13) | func CasbinHandler() gin.HandlerFunc {
FILE: server/middleware/cors.go
function Cors (line 11) | func Cors() gin.HandlerFunc {
function CorsByRules (line 31) | func CorsByRules() gin.HandlerFunc {
function checkCors (line 65) | func checkCors(currentOrigin string) *config.CORSWhitelist {
FILE: server/middleware/email.go
function ErrorToEmail (line 18) | func ErrorToEmail() gin.HandlerFunc {
FILE: server/middleware/error.go
function GinRecovery (line 21) | func GinRecovery(stack bool) gin.HandlerFunc {
FILE: server/middleware/jwt.go
function JWTAuth (line 16) | func JWTAuth() gin.HandlerFunc {
function isBlacklist (line 86) | func isBlacklist(jwt string) bool {
FILE: server/middleware/limit_ip.go
type LimitConfig (line 16) | type LimitConfig struct
method LimitWithTime (line 27) | func (l LimitConfig) LimitWithTime() gin.HandlerFunc {
function DefaultGenerationKey (line 40) | func DefaultGenerationKey(c *gin.Context) string {
function DefaultCheckOrMark (line 44) | func DefaultCheckOrMark(key string, expire int, limit int) (err error) {
function DefaultLimit (line 55) | func DefaultLimit() gin.HandlerFunc {
function SetLimitWithTime (line 65) | func SetLimitWithTime(key string, limit int, expiration time.Duration) e...
FILE: server/middleware/loadtls.go
function LoadTls (line 12) | func LoadTls() gin.HandlerFunc {
FILE: server/middleware/logger.go
type LogLayout (line 15) | type LogLayout struct
type Logger (line 28) | type Logger struct
method SetLoggerMiddleware (line 41) | func (l Logger) SetLoggerMiddleware() gin.HandlerFunc {
function DefaultLogger (line 80) | func DefaultLogger() gin.HandlerFunc {
FILE: server/middleware/operation.go
function init (line 25) | func init() {
function OperationRecord (line 31) | func OperationRecord() gin.HandlerFunc {
type responseBodyWriter (line 121) | type responseBodyWriter struct
method Write (line 126) | func (r responseBodyWriter) Write(b []byte) (int, error) {
FILE: server/middleware/timeout.go
function TimeoutMiddleware (line 13) | func TimeoutMiddleware(timeout time.Duration) gin.HandlerFunc {
FILE: server/model/common/basetypes.go
type JSONMap (line 9) | type JSONMap
method Value (line 11) | func (m JSONMap) Value() (driver.Value, error) {
method Scan (line 18) | func (m *JSONMap) Scan(value interface{}) error {
type TreeNode (line 38) | type TreeNode interface
FILE: server/model/common/clearDB.go
type ClearDB (line 3) | type ClearDB struct
FILE: server/model/common/request/common.go
type PageInfo (line 8) | type PageInfo struct
method Paginate (line 14) | func (r *PageInfo) Paginate() func(db *gorm.DB) *gorm.DB {
type GetById (line 31) | type GetById struct
method Uint (line 35) | func (r *GetById) Uint() uint {
type IdsReq (line 39) | type IdsReq struct
type GetAuthorityId (line 44) | type GetAuthorityId struct
type Empty (line 48) | type Empty struct
FILE: server/model/common/response/common.go
type PageResult (line 3) | type PageResult struct
FILE: server/model/common/response/response.go
type Response (line 9) | type Response struct
constant ERROR (line 16) | ERROR = 7
constant SUCCESS (line 17) | SUCCESS = 0
function Result (line 20) | func Result(code int, data interface{}, msg string, c *gin.Context) {
function Ok (line 28) | func Ok(c *gin.Context) {
function OkWithMessage (line 32) | func OkWithMessage(message string, c *gin.Context) {
function OkWithData (line 36) | func OkWithData(data interface{}, c *gin.Context) {
function OkWithDetailed (line 40) | func OkWithDetailed(data interface{}, message string, c *gin.Context) {
function Fail (line 44) | func Fail(c *gin.Context) {
function FailWithMessage (line 48) | func FailWithMessage(message string, c *gin.Context) {
function NoAuth (line 52) | func NoAuth(message string, c *gin.Context) {
function FailWithDetailed (line 60) | func FailWithDetailed(data interface{}, message string, c *gin.Context) {
FILE: server/model/example/exa_attachment_category.go
type ExaAttachmentCategory (line 7) | type ExaAttachmentCategory struct
method TableName (line 14) | func (ExaAttachmentCategory) TableName() string {
FILE: server/model/example/exa_breakpoint_continue.go
type ExaFile (line 8) | type ExaFile struct
type ExaFileChunk (line 19) | type ExaFileChunk struct
FILE: server/model/example/exa_customer.go
type ExaCustomer (line 8) | type ExaCustomer struct
FILE: server/model/example/exa_file_upload_download.go
type ExaFileUploadAndDownload (line 7) | type ExaFileUploadAndDownload struct
method TableName (line 16) | func (ExaFileUploadAndDownload) TableName() string {
FILE: server/model/example/request/exa_file_upload_and_downloads.go
type ExaAttachmentCategorySearch (line 7) | type ExaAttachmentCategorySearch struct
FILE: server/model/example/response/exa_breakpoint_continue.go
type FilePathResponse (line 5) | type FilePathResponse struct
type FileResponse (line 9) | type FileResponse struct
FILE: server/model/example/response/exa_customer.go
type ExaCustomerResponse (line 5) | type ExaCustomerResponse struct
FILE: server/model/example/response/exa_file_upload_download.go
type ExaFileResponse (line 5) | type ExaFileResponse struct
FILE: server/model/system/request/jwt.go
type CustomClaims (line 9) | type CustomClaims struct
type BaseClaims (line 15) | type BaseClaims struct
FILE: server/model/system/request/sys_api.go
type SearchApiParams (line 9) | type SearchApiParams struct
type SetApiAuthorities (line 17) | type SetApiAuthorities struct
FILE: server/model/system/request/sys_api_token.go
type SysApiTokenSearch (line 8) | type SysApiTokenSearch struct
FILE: server/model/system/request/sys_authority_btn.go
type SysAuthorityBtnReq (line 3) | type SysAuthorityBtnReq struct
FILE: server/model/system/request/sys_auto_code.go
type AutoCode (line 13) | type AutoCode struct
method Apis (line 61) | func (r *AutoCode) Apis() []model.SysApi {
method Menu (line 102) | func (r *AutoCode) Menu(template string) model.SysBaseMenu {
method Pretreatment (line 120) | func (r *AutoCode) Pretreatment() error {
method History (line 212) | func (r *AutoCode) History() SysAutoHistoryCreate {
type DataSource (line 52) | type DataSource struct
type AutoCodeField (line 224) | type AutoCodeField struct
type AutoFunc (line 251) | type AutoFunc struct
type InitMenu (line 272) | type InitMenu struct
type InitApi (line 278) | type InitApi struct
type InitDictionary (line 283) | type InitDictionary struct
type LLMAutoCode (line 288) | type LLMAutoCode struct
FILE: server/model/system/request/sys_auto_code_mcp.go
type AutoMcpTool (line 3) | type AutoMcpTool struct
FILE: server/model/system/request/sys_auto_code_package.go
type SysAutoCodePackageCreate (line 8) | type SysAutoCodePackageCreate struct
method AutoCode (line 16) | func (r *SysAutoCodePackageCreate) AutoCode() AutoCode {
method Create (line 23) | func (r *SysAutoCodePackageCreate) Create() model.SysAutoCodePackage {
FILE: server/model/system/request/sys_auto_history.go
type SysAutoHistoryCreate (line 8) | type SysAutoHistoryCreate struct
method Create (line 22) | func (r *SysAutoHistoryCreate) Create() model.SysAutoCodeHistory {
type SysAutoHistoryRollBack (line 43) | type SysAutoHistoryRollBack struct
method ApiIds (line 50) | func (r *SysAutoHistoryRollBack) ApiIds(entity model.SysAutoCodeHistor...
FILE: server/model/system/request/sys_casbin.go
type CasbinInfo (line 4) | type CasbinInfo struct
type CasbinInReceive (line 10) | type CasbinInReceive struct
function DefaultCasbin (line 15) | func DefaultCasbin() []CasbinInfo {
FILE: server/model/system/request/sys_dictionary.go
type SysDictionarySearch (line 3) | type SysDictionarySearch struct
type ImportSysDictionaryRequest (line 7) | type ImportSysDictionaryRequest struct
FILE: server/model/system/request/sys_dictionary_detail.go
type SysDictionaryDetailSearch (line 8) | type SysDictionaryDetailSearch struct
type CreateSysDictionaryDetailRequest (line 16) | type CreateSysDictionaryDetailRequest struct
type UpdateSysDictionaryDetailRequest (line 27) | type UpdateSysDictionaryDetailRequest struct
type GetDictionaryDetailsByParentRequest (line 39) | type GetDictionaryDetailsByParentRequest struct
FILE: server/model/system/request/sys_error.go
type SysErrorSearch (line 9) | type SysErrorSearch struct
FILE: server/model/system/request/sys_export_template.go
type SysExportTemplateSearch (line 9) | type SysExportTemplateSearch struct
FILE: server/model/system/request/sys_init.go
type InitDB (line 9) | type InitDB struct
method MysqlEmptyDsn (line 23) | func (i *InitDB) MysqlEmptyDsn() string {
method PgsqlEmptyDsn (line 35) | func (i *InitDB) PgsqlEmptyDsn() string {
method SqliteEmptyDsn (line 47) | func (i *InitDB) SqliteEmptyDsn() string {
method MssqlEmptyDsn (line 52) | func (i *InitDB) MssqlEmptyDsn() string {
method ToMysqlConfig (line 58) | func (i *InitDB) ToMysqlConfig() config.Mysql {
method ToPgsqlConfig (line 76) | func (i *InitDB) ToPgsqlConfig() config.Pgsql {
method ToSqliteConfig (line 94) | func (i *InitDB) ToSqliteConfig() config.Sqlite {
method ToMssqlConfig (line 110) | func (i *InitDB) ToMssqlConfig() config.Mssql {
FILE: server/model/system/request/sys_login_log.go
type SysLoginLogSearch (line 8) | type SysLoginLogSearch struct
FILE: server/model/system/request/sys_menu.go
type AddMenuAuthorityInfo (line 9) | type AddMenuAuthorityInfo struct
type SetMenuAuthorities (line 15) | type SetMenuAuthorities struct
function DefaultMenu (line 20) | func DefaultMenu() []system.SysBaseMenu {
FILE: server/model/system/request/sys_operation_record.go
type SysOperationRecordSearch (line 8) | type SysOperationRecordSearch struct
FILE: server/model/system/request/sys_params.go
type SysParamsSearch (line 8) | type SysParamsSearch struct
FILE: server/model/system/request/sys_skills.go
type SkillToolRequest (line 5) | type SkillToolRequest struct
type SkillDetailRequest (line 9) | type SkillDetailRequest struct
type SkillDeleteRequest (line 14) | type SkillDeleteRequest struct
type SkillPackageRequest (line 19) | type SkillPackageRequest struct
type SkillSaveRequest (line 24) | type SkillSaveRequest struct
type SkillScriptCreateRequest (line 32) | type SkillScriptCreateRequest struct
type SkillResourceCreateRequest (line 39) | type SkillResourceCreateRequest struct
type SkillReferenceCreateRequest (line 45) | type SkillReferenceCreateRequest struct
type SkillTemplateCreateRequest (line 51) | type SkillTemplateCreateRequest struct
type SkillFileRequest (line 57) | type SkillFileRequest struct
type SkillFileSaveRequest (line 63) | type SkillFileSaveRequest struct
type SkillGlobalConstraintSaveRequest (line 70) | type SkillGlobalConstraintSaveRequest struct
type DownloadOnlineSkillReq (line 76) | type DownloadOnlineSkillReq struct
FILE: server/model/system/request/sys_user.go
type Register (line 9) | type Register struct
type Login (line 22) | type Login struct
type ChangePasswordReq (line 30) | type ChangePasswordReq struct
type ResetPassword (line 36) | type ResetPassword struct
type SetUserAuth (line 42) | type SetUserAuth struct
type SetUserAuthorities (line 47) | type SetUserAuthorities struct
type ChangeUserInfo (line 52) | type ChangeUserInfo struct
type GetUserList (line 63) | type GetUserList struct
type SetRoleUsers (line 74) | type SetRoleUsers struct
FILE: server/model/system/request/sys_version.go
type SysVersionSearch (line 9) | type SysVersionSearch struct
type ExportVersionRequest (line 17) | type ExportVersionRequest struct
type ImportVersionRequest (line 27) | type ImportVersionRequest struct
type VersionInfo (line 35) | type VersionInfo struct
FILE: server/model/system/response/sys_api.go
type SysAPIResponse (line 7) | type SysAPIResponse struct
type SysAPIListResponse (line 11) | type SysAPIListResponse struct
type SysSyncApis (line 15) | type SysSyncApis struct
FILE: server/model/system/response/sys_authority.go
type SysAuthorityResponse (line 5) | type SysAuthorityResponse struct
type SysAuthorityCopyResponse (line 9) | type SysAuthorityCopyResponse struct
FILE: server/model/system/response/sys_authority_btn.go
type SysAuthorityBtnRes (line 3) | type SysAuthorityBtnRes struct
FILE: server/model/system/response/sys_auto_code.go
type Db (line 5) | type Db struct
type Table (line 9) | type Table struct
type Column (line 13) | type Column struct
type PluginInfo (line 21) | type PluginInfo struct
FILE: server/model/system/response/sys_captcha.go
type SysCaptchaResponse (line 3) | type SysCaptchaResponse struct
FILE: server/model/system/response/sys_casbin.go
type PolicyPathResponse (line 7) | type PolicyPathResponse struct
FILE: server/model/system/response/sys_menu.go
type SysMenusResponse (line 5) | type SysMenusResponse struct
type SysBaseMenusResponse (line 9) | type SysBaseMenusResponse struct
type SysBaseMenuResponse (line 13) | type SysBaseMenuResponse struct
FILE: server/model/system/response/sys_system.go
type SysConfigResponse (line 5) | type SysConfigResponse struct
FILE: server/model/system/response/sys_user.go
type SysUserResponse (line 7) | type SysUserResponse struct
type LoginResponse (line 11) | type LoginResponse struct
FILE: server/model/system/response/sys_version.go
type ExportVersionResponse (line 9) | type ExportVersionResponse struct
FILE: server/model/system/sys_api.go
type SysApi (line 7) | type SysApi struct
method TableName (line 15) | func (SysApi) TableName() string {
type SysIgnoreApi (line 19) | type SysIgnoreApi struct
method TableName (line 26) | func (SysIgnoreApi) TableName() string {
FILE: server/model/system/sys_api_token.go
type SysApiToken (line 8) | type SysApiToken struct
FILE: server/model/system/sys_authority.go
type SysAuthority (line 7) | type SysAuthority struct
method TableName (line 21) | func (SysAuthority) TableName() string {
FILE: server/model/system/sys_authority_btn.go
type SysAuthorityBtn (line 3) | type SysAuthorityBtn struct
FILE: server/model/system/sys_authority_menu.go
type SysMenu (line 3) | type SysMenu struct
type SysAuthorityMenu (line 12) | type SysAuthorityMenu struct
method TableName (line 17) | func (s SysAuthorityMenu) TableName() string {
FILE: server/model/system/sys_auto_code_history.go
type SysAutoCodeHistory (line 13) | type SysAutoCodeHistory struct
method BeforeCreate (line 32) | func (s *SysAutoCodeHistory) BeforeCreate(db *gorm.DB) error {
method TableName (line 66) | func (s *SysAutoCodeHistory) TableName() string {
FILE: server/model/system/sys_auto_code_package.go
type SysAutoCodePackage (line 7) | type SysAutoCodePackage struct
method TableName (line 16) | func (s *SysAutoCodePackage) TableName() string {
FILE: server/model/system/sys_base_menu.go
type SysBaseMenu (line 7) | type SysBaseMenu struct
method TableName (line 41) | func (SysBaseMenu) TableName() string {
type Meta (line 23) | type Meta struct
type SysBaseMenuParameter (line 33) | type SysBaseMenuParameter struct
FILE: server/model/system/sys_dictionary.go
type SysDictionary (line 9) | type SysDictionary struct
method TableName (line 20) | func (SysDictionary) TableName() string {
FILE: server/model/system/sys_dictionary_detail.go
type SysDictionaryDetail (line 9) | type SysDictionaryDetail struct
method TableName (line 24) | func (SysDictionaryDetail) TableName() string {
FILE: server/model/system/sys_error.go
type SysError (line 9) | type SysError struct
method TableName (line 19) | func (SysError) TableName() string {
FILE: server/model/system/sys_export_template.go
type SysExportTemplate (line 9) | type SysExportTemplate struct
type JoinTemplate (line 24) | type JoinTemplate struct
method TableName (line 32) | func (JoinTemplate) TableName() string {
type Condition (line 36) | type Condition struct
method TableName (line 44) | func (Condition) TableName() string {
FILE: server/model/system/sys_jwt_blacklist.go
type JwtBlacklist (line 7) | type JwtBlacklist struct
FILE: server/model/system/sys_login_log.go
type SysLoginLog (line 7) | type SysLoginLog struct
FILE: server/model/system/sys_menu_btn.go
type SysBaseMenuBtn (line 5) | type SysBaseMenuBtn struct
FILE: server/model/system/sys_operation_record.go
type SysOperationRecord (line 11) | type SysOperationRecord struct
FILE: server/model/system/sys_params.go
type SysParams (line 9) | type SysParams struct
method TableName (line 18) | func (SysParams) TableName() string {
FILE: server/model/system/sys_skills.go
type SkillMeta (line 3) | type SkillMeta struct
type SkillDetail (line 11) | type SkillDetail struct
type SkillTool (line 22) | type SkillTool struct
FILE: server/model/system/sys_system.go
type System (line 8) | type System struct
FILE: server/model/system/sys_user.go
type Login (line 9) | type Login interface
type SysUser (line 20) | type SysUser struct
method TableName (line 36) | func (SysUser) TableName() string {
method GetUsername (line 40) | func (s *SysUser) GetUsername() string {
method GetNickname (line 44) | func (s *SysUser) GetNickname() string {
method GetUUID (line 48) | func (s *SysUser) GetUUID() uuid.UUID {
method GetUserId (line 52) | func (s *SysUser) GetUserId() uint {
method GetAuthorityId (line 56) | func (s *SysUser) GetAuthorityId() uint {
method GetUserInfo (line 60) | func (s *SysUser) GetUserInfo() any {
FILE: server/model/system/sys_user_authority.go
type SysUserAuthority (line 4) | type SysUserAuthority struct
method TableName (line 9) | func (s *SysUserAuthority) TableName() string {
FILE: server/model/system/sys_version.go
type SysVersion (line 9) | type SysVersion struct
method TableName (line 18) | func (SysVersion) TableName() string {
FILE: server/plugin/announcement/api/enter.go
type api (line 10) | type api struct
FILE: server/plugin/announcement/api/info.go
type info (line 14) | type info struct
method CreateInfo (line 25) | func (a *info) CreateInfo(c *gin.Context) {
method DeleteInfo (line 50) | func (a *info) DeleteInfo(c *gin.Context) {
method DeleteInfoByIds (line 69) | func (a *info) DeleteInfoByIds(c *gin.Context) {
method UpdateInfo (line 88) | func (a *info) UpdateInfo(c *gin.Context) {
method FindInfo (line 113) | func (a *info) FindInfo(c *gin.Context) {
method GetInfoList (line 133) | func (a *info) GetInfoList(c *gin.Context) {
method GetInfoDataSource (line 161) | func (a *info) GetInfoDataSource(c *gin.Context) {
method GetInfoPublic (line 180) | func (a *info) GetInfoPublic(c *gin.Context) {
FILE: server/plugin/announcement/config/config.go
type Config (line 3) | type Config struct
FILE: server/plugin/announcement/gen/gen.go
function main (line 11) | func main() {
FILE: server/plugin/announcement/initialize/api.go
function Api (line 9) | func Api(ctx context.Context) {
FILE: server/plugin/announcement/initialize/dictionary.go
function Dictionary (line 9) | func Dictionary(ctx context.Context) {
FILE: server/plugin/announcement/initialize/gorm.go
function Gorm (line 12) | func Gorm(ctx context.Context) {
FILE: server/plugin/announcement/initialize/menu.go
function Menu (line 9) | func Menu(ctx context.Context) {
FILE: server/plugin/announcement/initialize/router.go
function Router (line 10) | func Router(engine *gin.Engine) {
FILE: server/plugin/announcement/initialize/viper.go
function Viper (line 11) | func Viper() {
FILE: server/plugin/announcement/model/info.go
type Info (line 9) | type Info struct
method TableName (line 18) | func (Info) TableName() string {
FILE: server/plugin/announcement/model/request/info.go
type InfoSearch (line 8) | type InfoSearch struct
FILE: server/plugin/announcement/plugin.go
type plugin (line 14) | type plugin struct
method Register (line 20) | func (p *plugin) Register(group *gin.Engine) {
function init (line 16) | func init() {
FILE: server/plugin/announcement/router/enter.go
type router (line 10) | type router struct
FILE: server/plugin/announcement/router/info.go
type info (line 10) | type info struct
method Init (line 13) | func (r *info) Init(public *gin.RouterGroup, private *gin.RouterGroup) {
FILE: server/plugin/announcement/service/enter.go
type service (line 5) | type service struct
FILE: server/plugin/announcement/service/info.go
type info (line 11) | type info struct
method CreateInfo (line 15) | func (s *info) CreateInfo(info *model.Info) (err error) {
method DeleteInfo (line 22) | func (s *info) DeleteInfo(ID string) (err error) {
method DeleteInfoByIds (line 29) | func (s *info) DeleteInfoByIds(IDs []string) (err error) {
method UpdateInfo (line 36) | func (s *info) UpdateInfo(info model.Info) (err error) {
method GetInfo (line 43) | func (s *info) GetInfo(ID string) (info model.Info, err error) {
method GetInfoInfoList (line 50) | func (s *info) GetInfoInfoList(info request.InfoSearch) (list []model....
method GetInfoDataSource (line 71) | func (s *info) GetInfoDataSource() (res map[string][]map[string]any, e...
FILE: server/plugin/email/api/enter.go
type ApiGroup (line 3) | type ApiGroup struct
FILE: server/plugin/email/api/sys_email.go
type EmailApi (line 12) | type EmailApi struct
method EmailTest (line 21) | func (s *EmailApi) EmailTest(c *gin.Context) {
method SendEmail (line 39) | func (s *EmailApi) SendEmail(c *gin.Context) {
FILE: server/plugin/email/config/email.go
type Email (line 3) | type Email struct
FILE: server/plugin/email/main.go
type emailPlugin (line 9) | type emailPlugin struct
method Register (line 23) | func (*emailPlugin) Register(group *gin.RouterGroup) {
method RouterPath (line 27) | func (*emailPlugin) RouterPath() string {
function CreateEmailPlug (line 11) | func CreateEmailPlug(To, From, Host, Secret, Nickname string, Port int, ...
FILE: server/plugin/email/model/response/email.go
type Email (line 3) | type Email struct
FILE: server/plugin/email/router/enter.go
type RouterGroup (line 3) | type RouterGroup struct
FILE: server/plugin/email/router/sys_email.go
type EmailRouter (line 9) | type EmailRouter struct
method InitEmailRouter (line 11) | func (s *EmailRouter) InitEmailRouter(Router *gin.RouterGroup) {
FILE: server/plugin/email/service/enter.go
type ServiceGroup (line 3) | type ServiceGroup struct
FILE: server/plugin/email/service/sys_email.go
type EmailService (line 7) | type EmailService struct
method EmailTest (line 14) | func (e *EmailService) EmailTest() (err error) {
method SendEmail (line 29) | func (e *EmailService) SendEmail(to, subject, body string) (err error) {
FILE: server/plugin/email/utils/email.go
function Email (line 20) | func Email(To, subject string, body string) error {
function ErrorToEmail (line 31) | func ErrorToEmail(subject string, body string) error {
function EmailTest (line 45) | func EmailTest(subject string, body string) error {
function send (line 56) | func send(to []string, subject string, body string) error {
type loginAuth (line 91) | type loginAuth struct
method Start (line 99) | func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, er...
method Next (line 103) | func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
function LoginAuth (line 95) | func LoginAuth(username, password string) smtp.Auth {
FILE: server/plugin/plugin-tool/utils/check.go
function getPluginName (line 23) | func getPluginName() string {
function RegisterApis (line 40) | func RegisterApis(apis ...system.SysApi) {
function RegisterMenus (line 63) | func RegisterMenus(menus ...system.SysBaseMenu) {
function RegisterDictionaries (line 96) | func RegisterDictionaries(dictionaries ...system.SysDictionary) {
function Pointer (line 129) | func Pointer[T any](in T) *T {
function GetPluginData (line 133) | func GetPluginData(pluginName string) ([]system.SysApi, []system.SysBase...
FILE: server/router/enter.go
type RouterGroup (line 10) | type RouterGroup struct
FILE: server/router/example/enter.go
type RouterGroup (line 7) | type RouterGroup struct
FILE: server/router/example/exa_attachment_category.go
type AttachmentCategoryRouter (line 7) | type AttachmentCategoryRouter struct
method InitAttachmentCategoryRouterRouter (line 9) | func (r *AttachmentCategoryRouter) InitAttachmentCategoryRouterRouter(...
FILE: server/router/example/exa_customer.go
type CustomerRouter (line 8) | type CustomerRouter struct
method InitCustomerRouter (line 10) | func (e *CustomerRouter) InitCustomerRouter(Router *gin.RouterGroup) {
FILE: server/router/example/exa_file_upload_and_download.go
type FileUploadAndDownloadRouter (line 7) | type FileUploadAndDownloadRouter struct
method InitFileUploadAndDownloadRouter (line 9) | func (e *FileUploadAndDownloadRouter) InitFileUploadAndDownloadRouter(...
FILE: server/router/system/enter.go
type RouterGroup (line 5) | type RouterGroup struct
FILE: server/router/system/sys_api.go
type ApiRouter (line 8) | type ApiRouter struct
method InitApiRouter (line 10) | func (s *ApiRouter) InitApiRouter(Router *gin.RouterGroup, RouterPub *...
FILE: server/router/system/sys_api_token.go
type ApiTokenRouter (line 9) | type ApiTokenRouter struct
method InitApiTokenRouter (line 11) | func (s *ApiTokenRouter) InitApiTokenRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_authority.go
type AuthorityRouter (line 8) | type AuthorityRouter struct
method InitAuthorityRouter (line 10) | func (s *AuthorityRouter) InitAuthorityRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_authority_btn.go
type AuthorityBtnRouter (line 7) | type AuthorityBtnRouter struct
method InitAuthorityBtnRouterRouter (line 11) | func (s *AuthorityBtnRouter) InitAuthorityBtnRouterRouter(Router *gin....
FILE: server/router/system/sys_auto_code.go
type AutoCodeRouter (line 7) | type AutoCodeRouter struct
method InitAutoCodeRouter (line 9) | func (s *AutoCodeRouter) InitAutoCodeRouter(Router *gin.RouterGroup, R...
FILE: server/router/system/sys_auto_code_history.go
type AutoCodeHistoryRouter (line 7) | type AutoCodeHistoryRouter struct
method InitAutoCodeHistoryRouter (line 9) | func (s *AutoCodeRouter) InitAutoCodeHistoryRouter(Router *gin.RouterGro...
FILE: server/router/system/sys_base.go
type BaseRouter (line 7) | type BaseRouter struct
method InitBaseRouter (line 9) | func (s *BaseRouter) InitBaseRouter(Router *gin.RouterGroup) (R gin.IR...
FILE: server/router/system/sys_casbin.go
type CasbinRouter (line 8) | type CasbinRouter struct
method InitCasbinRouter (line 10) | func (s *CasbinRouter) InitCasbinRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_dictionary.go
type DictionaryRouter (line 8) | type DictionaryRouter struct
method InitSysDictionaryRouter (line 10) | func (s *DictionaryRouter) InitSysDictionaryRouter(Router *gin.RouterG...
FILE: server/router/system/sys_dictionary_detail.go
type DictionaryDetailRouter (line 8) | type DictionaryDetailRouter struct
method InitSysDictionaryDetailRouter (line 10) | func (s *DictionaryDetailRouter) InitSysDictionaryDetailRouter(Router ...
FILE: server/router/system/sys_error.go
type SysErrorRouter (line 8) | type SysErrorRouter struct
method InitSysErrorRouter (line 11) | func (s *SysErrorRouter) InitSysErrorRouter(Router *gin.RouterGroup, P...
FILE: server/router/system/sys_export_template.go
type SysExportTemplateRouter (line 8) | type SysExportTemplateRouter struct
method InitSysExportTemplateRouter (line 12) | func (s *SysExportTemplateRouter) InitSysExportTemplateRouter(Router *...
FILE: server/router/system/sys_initdb.go
type InitRouter (line 7) | type InitRouter struct
method InitInitRouter (line 9) | func (s *InitRouter) InitInitRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_jwt.go
type JwtRouter (line 7) | type JwtRouter struct
method InitJwtRouter (line 9) | func (s *JwtRouter) InitJwtRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_login_log.go
type LoginLogRouter (line 9) | type LoginLogRouter struct
method InitLoginLogRouter (line 11) | func (s *LoginLogRouter) InitLoginLogRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_menu.go
type MenuRouter (line 8) | type MenuRouter struct
method InitMenuRouter (line 10) | func (s *MenuRouter) InitMenuRouter(Router *gin.RouterGroup) (R gin.IR...
FILE: server/router/system/sys_operation_record.go
type OperationRecordRouter (line 7) | type OperationRecordRouter struct
method InitSysOperationRecordRouter (line 9) | func (s *OperationRecordRouter) InitSysOperationRecordRouter(Router *g...
FILE: server/router/system/sys_params.go
type SysParamsRouter (line 8) | type SysParamsRouter struct
method InitSysParamsRouter (line 11) | func (s *SysParamsRouter) InitSysParamsRouter(Router *gin.RouterGroup,...
FILE: server/router/system/sys_skills.go
type SkillsRouter (line 5) | type SkillsRouter struct
method InitSkillsRouter (line 7) | func (s *SkillsRouter) InitSkillsRouter(Router *gin.RouterGroup, pubRo...
FILE: server/router/system/sys_system.go
type SysRouter (line 8) | type SysRouter struct
method InitSystemRouter (line 10) | func (s *SysRouter) InitSystemRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_user.go
type UserRouter (line 8) | type UserRouter struct
method InitUserRouter (line 10) | func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup) {
FILE: server/router/system/sys_version.go
type SysVersionRouter (line 8) | type SysVersionRouter struct
method InitSysVersionRouter (line 11) | func (s *SysVersionRouter) InitSysVersionRouter(Router *gin.RouterGrou...
FILE: server/service/enter.go
type ServiceGroup (line 10) | type ServiceGroup struct
FILE: server/service/example/enter.go
type ServiceGroup (line 3) | type ServiceGroup struct
FILE: server/service/example/exa_attachment_category.go
type AttachmentCategoryService (line 10) | type AttachmentCategoryService struct
method AddCategory (line 13) | func (a *AttachmentCategoryService) AddCategory(req *example.ExaAttach...
method DeleteCategory (line 37) | func (a *AttachmentCategoryService) DeleteCategory(id *int) error {
method GetCategoryList (line 47) | func (a *AttachmentCategoryService) GetCategoryList() (res []*example....
method getChildrenList (line 57) | func (a *AttachmentCategoryService) getChildrenList(categories []examp...
FILE: server/service/example/exa_breakpoint_continue.go
type FileUploadAndDownloadService (line 11) | type FileUploadAndDownloadService struct
method FindOrCreateFile (line 21) | func (e *FileUploadAndDownloadService) FindOrCreateFile(fileMd5 string...
method CreateFileChunk (line 43) | func (e *FileUploadAndDownloadService) CreateFileChunk(id uint, fileCh...
method DeleteFileChunk (line 58) | func (e *FileUploadAndDownloadService) DeleteFileChunk(fileMd5 string,...
FILE: server/service/example/exa_customer.go
type CustomerService (line 11) | type CustomerService struct
method CreateExaCustomer (line 21) | func (exa *CustomerService) CreateExaCustomer(e example.ExaCustomer) (...
method DeleteExaCustomer (line 32) | func (exa *CustomerService) DeleteExaCustomer(e example.ExaCustomer) (...
method UpdateExaCustomer (line 43) | func (exa *CustomerService) UpdateExaCustomer(e *example.ExaCustomer) ...
method GetExaCustomer (line 54) | func (exa *CustomerService) GetExaCustomer(id uint) (customer example....
method GetCustomerInfoList (line 65) | func (exa *CustomerService) GetCustomerInfoList(sysUserAuthorityID uin...
FILE: server/service/example/exa_file_upload_download.go
method Upload (line 21) | func (e *FileUploadAndDownloadService) Upload(file example.ExaFileUpload...
method FindFile (line 31) | func (e *FileUploadAndDownloadService) FindFile(id uint) (example.ExaFil...
method DeleteFile (line 43) | func (e *FileUploadAndDownloadService) DeleteFile(file example.ExaFileUp...
method EditFileName (line 58) | func (e *FileUploadAndDownloadService) EditFileName(file example.ExaFile...
method GetFileRecordInfoList (line 69) | func (e *FileUploadAndDownloadService) GetFileRecordInfoList(info reques...
method UploadFile (line 96) | func (e *FileUploadAndDownloadService) UploadFile(header *multipart.File...
method ImportURL (line 128) | func (e *FileUploadAndDownloadService) ImportURL(file *[]example.ExaFile...
FILE: server/service/system/auto_code_history.go
type autoCodeHistory (line 26) | type autoCodeHistory struct
method Create (line 31) | func (s *autoCodeHistory) Create(ctx context.Context, info request.Sys...
method First (line 43) | func (s *autoCodeHistory) First(ctx context.Context, info common.GetBy...
method Repeat (line 55) | func (s *autoCodeHistory) Repeat(businessDB, structName, abbreviation,...
method RollBack (line 64) | func (s *autoCodeHistory) RollBack(ctx context.Context, info request.S...
method Delete (line 187) | func (s *autoCodeHistory) Delete(ctx context.Context, info common.GetB...
method GetList (line 198) | func (s *autoCodeHistory) GetList(ctx context.Context, info common.Pag...
method DropTable (line 211) | func (s *autoCodeHistory) DropTable(BusinessDb, tableName string) error {
FILE: server/service/system/auto_code_llm.go
method LLMAuto (line 18) | func (s *AutoCodeService) LLMAuto(ctx context.Context, llm common.JSONMa...
FILE: server/service/system/auto_code_mcp.go
method CreateMcp (line 14) | func (s *autoCodeTemplate) CreateMcp(ctx context.Context, info request.A...
FILE: server/service/system/auto_code_package.go
type autoCodePackage (line 25) | type autoCodePackage struct
method Create (line 30) | func (s *autoCodePackage) Create(ctx context.Context, info *request.Sy...
method Delete (line 110) | func (s *autoCodePackage) Delete(ctx context.Context, info common.GetB...
method DeleteByNames (line 121) | func (s *autoCodePackage) DeleteByNames(ctx context.Context, names []s...
method All (line 135) | func (s *autoCodePackage) All(ctx context.Context) (entities []model.S...
method Templates (line 278) | func (s *autoCodePackage) Templates(ctx context.Context) ([]string, er...
method templates (line 304) | func (s *autoCodePackage) templates(ctx context.Context, entity model....
FILE: server/service/system/auto_code_package_test.go
function Test_autoCodePackage_Create (line 12) | func Test_autoCodePackage_Create(t *testing.T) {
function Test_autoCodePackage_templates (line 55) | func Test_autoCodePackage_templates(t *testing.T) {
FILE: server/service/system/auto_code_plugin.go
type autoCodePlugin (line 31) | type autoCodePlugin struct
method Install (line 34) | func (s *autoCodePlugin) Install(file *multipart.FileHeader) (web, ser...
method PubPlug (line 225) | func (s *autoCodePlugin) PubPlug(plugName string) (zipPath string, err...
method InitMenu (line 277) | func (s *autoCodePlugin) InitMenu(menuInfo request.InitMenu) (err erro...
method InitAPI (line 320) | func (s *autoCodePlugin) InitAPI(apiInfo request.InitApi) (err error) {
method InitDictionary (line 345) | func (s *autoCodePlugin) InitDictionary(dictInfo request.InitDictionar...
method Remove (line 370) | func (s *autoCodePlugin) Remove(pluginName string, pluginType string) ...
function installation (line 131) | func installation(path string, formPath string, toPath string) error {
function ensurePluginRegisterImport (line 149) | func ensurePluginRegisterImport(packageName string) error {
function filterFile (line 207) | func filterFile(paths []string) []string {
function skipMacSpecialDocument (line 218) | func skipMacSpecialDocument(_ os.FileInfo, src, _ string) (bool, error) {
function GetMenuIds (line 443) | func GetMenuIds(menu system.SysBaseMenu, ids *[]int) {
function removePluginRegisterImport (line 453) | func removePluginRegisterImport(packageName string) error {
FILE: server/service/system/auto_code_template.go
type autoCodeTemplate (line 27) | type autoCodeTemplate struct
method checkPackage (line 29) | func (s *autoCodeTemplate) checkPackage(Pkg string, template string) (...
method Create (line 58) | func (s *autoCodeTemplate) Create(ctx context.Context, info request.Au...
method Preview (line 189) | func (s *autoCodeTemplate) Preview(ctx context.Context, info request.A...
method generate (line 220) | func (s *autoCodeTemplate) generate(ctx context.Context, info request....
method AddFunc (line 274) | func (s *autoCodeTemplate) AddFunc(info request.AutoFunc) error {
method GetApiAndServer (line 298) | func (s *autoCodeTemplate) GetApiAndServer(info request.AutoFunc) (map...
method getTemplateStr (line 324) | func (s *autoCodeTemplate) getTemplateStr(t string, info request.AutoF...
method addTemplateToAst (line 339) | func (s *autoCodeTemplate) addTemplateToAst(t string, info request.Aut...
method addTemplateToFile (line 403) | func (s *autoCodeTemplate) addTemplateToFile(t string, info request.Au...
FILE: server/service/system/auto_code_template_test.go
function Test_autoCodeTemplate_Create (line 11) | func Test_autoCodeTemplate_Create(t *testing.T) {
function Test_autoCodeTemplate_Preview (line 33) | func Test_autoCodeTemplate_Preview(t *testing.T) {
FILE: server/service/system/enter.go
type ServiceGroup (line 3) | type ServiceGroup struct
FILE: server/service/system/jwt_black_list.go
type JwtService (line 12) | type JwtService struct
method JsonInBlacklist (line 22) | func (jwtService *JwtService) JsonInBlacklist(jwtList system.JwtBlackl...
method GetRedisJWT (line 37) | func (jwtService *JwtService) GetRedisJWT(userName string) (redisJWT s...
function LoadAll (line 42) | func LoadAll() {
FILE: server/service/system/sys_api.go
type ApiService (line 21) | type ApiService struct
method CreateApi (line 25) | func (apiService *ApiService) CreateApi(api system.SysApi) (err error) {
method GetApiGroups (line 32) | func (apiService *ApiService) GetApiGroups() (groups []string, groupAp...
method SyncApi (line 55) | func (apiService *ApiService) SyncApi() (newApis, deleteApis, ignoreAp...
method IgnoreApi (line 129) | func (apiService *ApiService) IgnoreApi(ignoreApi system.SysIgnoreApi)...
method EnterSyncApi (line 136) | func (apiService *ApiService) EnterSyncApi(syncApis systemRes.SysSyncA...
method DeleteApi (line 162) | func (apiService *ApiService) DeleteApi(api system.SysApi) (err error) {
method GetAPIInfoList (line 182) | func (apiService *ApiService) GetAPIInfoList(api system.SysApi, info r...
method GetAllApis (line 237) | func (apiService *ApiService) GetAllApis(authorityID uint) (apis []sys...
method GetApiById (line 265) | func (apiService *ApiService) GetApiById(id int) (api system.SysApi, e...
method UpdateApi (line 276) | func (apiService *ApiService) UpdateApi(api system.SysApi) (err error) {
method DeleteApisByIds (line 310) | func (apiService *ApiService) DeleteApisByIds(ids request.IdsReq) (err...
FILE: server/service/system/sys_api_token.go
type ApiTokenService (line 13) | type ApiTokenService struct
method CreateApiToken (line 15) | func (apiVersion *ApiTokenService) CreateApiToken(apiToken system.SysA...
method GetApiTokenList (line 70) | func (apiVersion *ApiTokenService) GetApiTokenList(info sysReq.SysApiT...
method DeleteApiToken (line 92) | func (apiVersion *ApiTokenService) DeleteApiToken(id uint) error {
FILE: server/service/system/sys_authority.go
type AuthorityService (line 24) | type AuthorityService struct
method CreateAuthority (line 28) | func (authorityService *AuthorityService) CreateAuthority(auth system....
method CopyAuthority (line 62) | func (authorityService *AuthorityService) CopyAuthority(adminAuthority...
method UpdateAuthority (line 114) | func (authorityService *AuthorityService) UpdateAuthority(auth system....
method DeleteAuthority (line 131) | func (authorityService *AuthorityService) DeleteAuthority(auth *system...
method GetAuthorityInfoList (line 186) | func (authorityService *AuthorityService) GetAuthorityInfoList(authori...
method GetStructAuthorityList (line 219) | func (authorityService *AuthorityService) GetStructAuthorityList(autho...
method CheckAuthorityIDAuth (line 239) | func (authorityService *AuthorityService) CheckAuthorityIDAuth(authori...
method GetAuthorityInfo (line 266) | func (authorityService *AuthorityService) GetAuthorityInfo(auth system...
method SetDataAuthority (line 277) | func (authorityService *AuthorityService) SetDataAuthority(adminAuthor...
method SetMenuAuthority (line 303) | func (authorityService *AuthorityService) SetMenuAuthority(auth *syste...
method findChildrenAuthority (line 316) | func (authorityService *AuthorityService) findChildrenAuthority(author...
method GetParentAuthorityID (line 326) | func (authorityService *AuthorityService) GetParentAuthorityID(authori...
method GetUserIdsByAuthorityId (line 336) | func (authorityService *AuthorityService) GetUserIdsByAuthorityId(auth...
method SetRoleUsers (line 350) | func (authorityService *AuthorityService) SetRoleUsers(authorityId uin...
FILE: server/service/system/sys_authority_btn.go
type AuthorityBtnService (line 12) | type AuthorityBtnService struct
method GetAuthorityBtn (line 16) | func (a *AuthorityBtnService) GetAuthorityBtn(req request.SysAuthority...
method SetAuthorityBtn (line 30) | func (a *AuthorityBtnService) SetAuthorityBtn(req request.SysAuthority...
method CanRemoveAuthorityBtn (line 54) | func (a *AuthorityBtnService) CanRemoveAuthorityBtn(ID string) (err er...
FILE: server/service/system/sys_auto_code_interface.go
type AutoCodeService (line 8) | type AutoCodeService struct
method Database (line 16) | func (autoCodeService *AutoCodeService) Database(businessDB string) Da...
type Database (line 10) | type Database interface
FILE: server/service/system/sys_auto_code_mssql.go
type autoCodeMssql (line 11) | type autoCodeMssql struct
method GetDB (line 16) | func (s *autoCodeMssql) GetDB(businessDB string) (data []response.Db, ...
method GetTables (line 30) | func (s *autoCodeMssql) GetTables(businessDB string, dbName string) (d...
method GetColumn (line 46) | func (s *autoCodeMssql) GetColumn(businessDB string, tableName string,...
FILE: server/service/system/sys_auto_code_mysql.go
type autoCodeMysql (line 10) | type autoCodeMysql struct
method GetDB (line 15) | func (s *autoCodeMysql) GetDB(businessDB string) (data []response.Db, ...
method GetTables (line 29) | func (s *autoCodeMysql) GetTables(businessDB string, dbName string) (d...
method GetColumn (line 44) | func (s *autoCodeMysql) GetColumn(businessDB string, tableName string,...
FILE: server/service/system/sys_auto_code_oracle.go
type autoCodeOracle (line 10) | type autoCodeOracle struct
method GetDB (line 15) | func (s *autoCodeOracle) GetDB(businessDB string) (data []response.Db,...
method GetTables (line 25) | func (s *autoCodeOracle) GetTables(businessDB string, dbName string) (...
method GetColumn (line 36) | func (s *autoCodeOracle) GetColumn(businessDB string, tableName string...
FILE: server/service/system/sys_auto_code_pgsql.go
type autoCodePgsql (line 10) | type autoCodePgsql struct
method GetDB (line 15) | func (a *autoCodePgsql) GetDB(businessDB string) (data []response.Db, ...
method GetTables (line 30) | func (a *autoCodePgsql) GetTables(businessDB string, dbName string) (d...
method GetColumn (line 46) | func (a *autoCodePgsql) GetColumn(businessDB string, tableName string,...
FILE: server/service/system/sys_auto_code_sqlite.go
type autoCodeSqlite (line 13) | type autoCodeSqlite struct
method GetDB (line 18) | func (a *autoCodeSqlite) GetDB(businessDB string) (data []response.Db,...
method GetTables (line 45) | func (a *autoCodeSqlite) GetTables(businessDB string, dbName string) (...
method GetColumn (line 63) | func (a *autoCodeSqlite) GetColumn(businessDB string, tableName string...
FILE: server/service/system/sys_base_menu.go
type BaseMenuService (line 11) | type BaseMenuService struct
method DeleteBaseMenu (line 21) | func (baseMenuService *BaseMenuService) DeleteBaseMenu(id int) (err er...
method UpdateBaseMenu (line 71) | func (baseMenuService *BaseMenuService) UpdateBaseMenu(menu system.Sys...
method GetBaseMenuById (line 144) | func (baseMenuService *BaseMenuService) GetBaseMenuById(id int) (menu ...
FILE: server/service/system/sys_casbin.go
type CasbinService (line 22) | type CasbinService struct
method UpdateCasbin (line 26) | func (casbinService *CasbinService) UpdateCasbin(adminAuthorityID, Aut...
method UpdateCasbinApi (line 82) | func (casbinService *CasbinService) UpdateCasbinApi(oldPath string, ne...
method GetPolicyPathByAuthorityId (line 101) | func (casbinService *CasbinService) GetPolicyPathByAuthorityId(Authori...
method ClearCasbin (line 120) | func (casbinService *CasbinService) ClearCasbin(v int, p ...string) bo...
method RemoveFilteredPolicy (line 132) | func (casbinService *CasbinService) RemoveFilteredPolicy(db *gorm.DB, ...
method SyncPolicy (line 142) | func (casbinService *CasbinService) SyncPolicy(db *gorm.DB, authorityI...
method AddPolicies (line 156) | func (casbinService *CasbinService) AddPolicies(db *gorm.DB, rules [][...
method FreshCasbin (line 169) | func (casbinService *CasbinService) FreshCasbin() (err error) {
method GetAuthoritiesByApi (line 176) | func (casbinService *CasbinService) GetAuthoritiesByApi(path, method s...
method SetApiAuthorities (line 192) | func (casbinService *CasbinService) SetApiAuthorities(path, method str...
FILE: server/service/system/sys_dictionary.go
type DictionaryService (line 21) | type DictionaryService struct
method CreateSysDictionary (line 25) | func (dictionaryService *DictionaryService) CreateSysDictionary(sysDic...
method DeleteSysDictionary (line 39) | func (dictionaryService *DictionaryService) DeleteSysDictionary(sysDic...
method UpdateSysDictionary (line 64) | func (dictionaryService *DictionaryService) UpdateSysDictionary(sysDic...
method GetSysDictionary (line 101) | func (dictionaryService *DictionaryService) GetSysDictionary(Type stri...
method GetSysDictionaryInfoList (line 121) | func (dictionaryService *DictionaryService) GetSysDictionaryInfoList(c...
method checkCircularReference (line 134) | func (dictionaryService *DictionaryService) checkCircularReference(cur...
method ExportSysDictionary (line 163) | func (dictionaryService *DictionaryService) ExportSysDictionary(id uin...
method ImportSysDictionary (line 206) | func (dictionaryService *DictionaryService) ImportSysDictionary(jsonSt...
FILE: server/service/system/sys_dictionary_detail.go
type DictionaryDetailService (line 18) | type DictionaryDetailService struct
method CreateSysDictionaryDetail (line 22) | func (dictionaryDetailService *DictionaryDetailService) CreateSysDicti...
method DeleteSysDictionaryDetail (line 51) | func (dictionaryDetailService *DictionaryDetailService) DeleteSysDicti...
method UpdateSysDictionaryDetail (line 72) | func (dictionaryDetailService *DictionaryDetailService) UpdateSysDicti...
method checkCircularReference (line 107) | func (dictionaryDetailService *DictionaryDetailService) checkCircularR...
method updateChildrenLevelAndPath (line 126) | func (dictionaryDetailService *DictionaryDetailService) updateChildren...
method GetSysDictionaryDetail (line 168) | func (dictionaryDetailService *DictionaryDetailService) GetSysDictiona...
method GetSysDictionaryDetailInfoList (line 179) | func (dictionaryDetailService *DictionaryDetailService) GetSysDictiona...
method GetDictionaryList (line 213) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryL...
method GetDictionaryTreeList (line 220) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryT...
method loadChildren (line 247) | func (dictionaryDetailService *DictionaryDetailService) loadChildren(d...
method GetDictionaryDetailsByParent (line 273) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryD...
method GetDictionaryListByType (line 310) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryL...
method GetDictionaryTreeListByType (line 318) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryT...
method GetDictionaryInfoByValue (line 349) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryI...
method GetDictionaryInfoByTypeValue (line 356) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryI...
method GetDictionaryPath (line 364) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryP...
method GetDictionaryPathByValue (line 385) | func (dictionaryDetailService *DictionaryDetailService) GetDictionaryP...
FILE: server/service/system/sys_error.go
type SysErrorService (line 12) | type SysErrorService struct
method CreateSysError (line 16) | func (sysErrorService *SysErrorService) CreateSysError(ctx context.Con...
method DeleteSysError (line 26) | func (sysErrorService *SysErrorService) DeleteSysError(ctx context.Con...
method DeleteSysErrorByIds (line 33) | func (sysErrorService *SysErrorService) DeleteSysErrorByIds(ctx contex...
method UpdateSysError (line 40) | func (sysErrorService *SysErrorService) UpdateSysError(ctx context.Con...
method GetSysError (line 47) | func (sysErrorService *SysErrorService) GetSysError(ctx context.Contex...
method GetSysErrorInfoList (line 54) | func (sysErrorService *SysErrorService) GetSysErrorInfoList(ctx contex...
method GetSysErrorSolution (line 86) | func (sysErrorService *SysErrorService) GetSysErrorSolution(ctx contex...
FILE: server/service/system/sys_export_template.go
type SysExportTemplateService (line 23) | type SysExportTemplateService struct
method CreateSysExportTemplate (line 30) | func (sysExportTemplateService *SysExportTemplateService) CreateSysExp...
method DeleteSysExportTemplate (line 37) | func (sysExportTemplateService *SysExportTemplateService) DeleteSysExp...
method DeleteSysExportTemplateByIds (line 44) | func (sysExportTemplateService *SysExportTemplateService) DeleteSysExp...
method UpdateSysExportTemplate (line 51) | func (sysExportTemplateService *SysExportTemplateService) UpdateSysExp...
method GetSysExportTemplate (line 89) | func (sysExportTemplateService *SysExportTemplateService) GetSysExport...
method GetSysExportTemplateInfoList (line 96) | func (sysExportTemplateService *SysExportTemplateService) GetSysExport...
method ExportExcel (line 130) | func (sysExportTemplateService *SysExportTemplateService) ExportExcel(...
method PreviewSQL (line 373) | func (sysExportTemplateService *SysExportTemplateService) PreviewSQL(t...
method ExportTemplate (line 558) | func (sysExportTemplateService *SysExportTemplateService) ExportTempla...
method hasDeletedAtColumn (line 605) | func (s *SysExportTemplateService) hasDeletedAtColumn(tableName string...
method ImportExcel (line 613) | func (sysExportTemplateService *SysExportTemplateService) ImportExcel(...
method parseExcelToMap (line 663) | func (sysExportTemplateService *SysExportTemplateService) parseExcelTo...
method importBySQL (line 692) | func (sysExportTemplateService *SysExportTemplateService) importBySQL(...
method importByGORM (line 701) | func (sysExportTemplateService *SysExportTemplateService) importByGORM...
function getColumnName (line 716) | func getColumnName(n int) string {
FILE: server/service/system/sys_initdb.go
constant Mysql (line 15) | Mysql = "mysql"
constant Pgsql (line 16) | Pgsql = "pgsql"
constant Sqlite (line 17) | Sqlite = "sqlite"
constant Mssql (line 18) | Mssql = "mssql"
constant InitSuccess (line 19) | InitSuccess = "\n[%v] --> 初始数据成功!\n"
constant InitDataExist (line 20) | InitDataExist = "\n[%v] --> %v 的初始数据已存在!\n"
constant InitDataFailed (line 21) | InitDataFailed = "\n[%v] --> %v 初始数据失败! \nerr: %+v\n"
constant InitDataSuccess (line 22) | InitDataSuccess = "\n[%v] --> %v 初始数据成功!\n"
constant InitOrderSystem (line 26) | InitOrderSystem = 10
constant InitOrderInternal (line 27) | InitOrderInternal = 1000
constant InitOrderExternal (line 28) | InitOrderExternal = 100000
type SubInitializer (line 38) | type SubInitializer interface
type TypedDBInitHandler (line 47) | type TypedDBInitHandler interface
type orderedInitializer (line 55) | type orderedInitializer struct
type initSlice (line 61) | type initSlice
method Len (line 179) | func (a initSlice) Len() int {
method Less (line 183) | func (a initSlice) Less(i, j int) bool {
method Swap (line 187) | func (a initSlice) Swap(i, j int) {
function RegisterInit (line 69) | func RegisterInit(order int, i SubInitializer) {
type InitDBService (line 87) | type InitDBService struct
method InitDB (line 90) | func (initDBService *InitDBService) InitDB(conf request.InitDB) (err e...
function createDatabase (line 142) | func createDatabase(dsn string, driver string, createSql string) error {
function createTables (line 161) | func createTables(ctx context.Context, inits initSlice) error {
FILE: server/service/system/sys_initdb_mssql.go
type MssqlInitHandler (line 17) | type MssqlInitHandler struct
method WriteConfig (line 24) | func (h MssqlInitHandler) WriteConfig(ctx context.Context) error {
method EnsureDB (line 41) | func (h MssqlInitHandler) EnsureDB(ctx context.Context, conf *request....
method InitTables (line 70) | func (h MssqlInitHandler) InitTables(ctx context.Context, inits initSl...
method InitData (line 74) | func (h MssqlInitHandler) InitData(ctx context.Context, inits initSlic...
function NewMssqlInitHandler (line 19) | func NewMssqlInitHandler() *MssqlInitHandler {
FILE: server/service/system/sys_initdb_mysql.go
type MysqlInitHandler (line 21) | type MysqlInitHandler struct
method WriteConfig (line 28) | func (h MysqlInitHandler) WriteConfig(ctx context.Context) error {
method EnsureDB (line 45) | func (h MysqlInitHandler) EnsureDB(ctx context.Context, conf *request....
method InitTables (line 75) | func (h MysqlInitHandler) InitTables(ctx context.Context, inits initSl...
method InitData (line 79) | func (h MysqlInitHandler) InitData(ctx context.Context, inits initSlic...
function NewMysqlInitHandler (line 23) | func NewMysqlInitHandler() *MysqlInitHandler {
FILE: server/service/system/sys_initdb_pgsql.go
type PgsqlInitHandler (line 21) | type PgsqlInitHandler struct
method WriteConfig (line 28) | func (h PgsqlInitHandler) WriteConfig(ctx context.Context) error {
method EnsureDB (line 45) | func (h PgsqlInitHandler) EnsureDB(ctx context.Context, conf *request....
method InitTables (line 79) | func (h PgsqlInitHandler) InitTables(ctx context.Context, inits initSl...
method InitData (line 83) | func (h PgsqlInitHandler) InitData(ctx context.Context, inits initSlic...
function NewPgsqlInitHandler (line 23) | func NewPgsqlInitHandler() *PgsqlInitHandler {
FILE: server/service/system/sys_initdb_sqlite.go
type SqliteInitHandler (line 18) | type SqliteInitHandler struct
method WriteConfig (line 25) | func (h SqliteInitHandler) WriteConfig(ctx context.Context) error {
method EnsureDB (line 42) | func (h SqliteInitHandler) EnsureDB(ctx context.Context, conf *request...
method InitTables (line 66) | func (h SqliteInitHandler) InitTables(ctx context.Context, inits initS...
method InitData (line 70) | func (h SqliteInitHandler) InitData(ctx context.Context, inits initSli...
function NewSqliteInitHandler (line 20) | func NewSqliteInitHandler() *SqliteInitHandler {
FILE: server/service/system/sys_login_log.go
type LoginLogService (line 10) | type LoginLogService struct
method CreateLoginLog (line 14) | func (loginLogService *LoginLogService) CreateLoginLog(loginLog system...
method DeleteLoginLogByIds (line 19) | func (loginLogService *LoginLogService) DeleteLoginLogByIds(ids reques...
method DeleteLoginLog (line 24) | func (loginLogService *LoginLogService) DeleteLoginLog(loginLog system...
method GetLoginLog (line 29) | func (loginLogService *LoginLogService) GetLoginLog(id uint) (loginLog...
method GetLoginLogInfoList (line 34) | func (loginLogService *LoginLogService) GetLoginLogInfoList(info syste...
FILE: server/service/system/sys_menu.go
type MenuService (line 18) | type MenuService struct
method getMenuTreeMap (line 22) | func (menuService *MenuService) getMenuTreeMap(authorityId uint) (tree...
method GetMenuTree (line 78) | func (menuService *MenuService) GetMenuTree(authorityId uint) (menus [...
method getChildrenList (line 93) | func (menuService *MenuService) getChildrenList(menu *system.SysMenu, ...
method GetInfoList (line 106) | func (menuService *MenuService) GetInfoList(authorityID uint) (list in...
method getBaseChildrenList (line 122) | func (menuService *MenuService) getBaseChildrenList(menu *system.SysBa...
method AddBaseMenu (line 136) | func (menuService *MenuService) AddBaseMenu(menu system.SysBaseMenu) e...
method getBaseMenuTreeMap (line 190) | func (menuService *MenuService) getBaseMenuTreeMap(authorityID uint) (...
method GetBaseMenuTree (line 226) | func (menuService *MenuService) GetBaseMenuTree(authorityID uint) (men...
method AddMenuAuthority (line 241) | func (menuService *MenuService) AddMenuAuthority(menus []system.SysBas...
method GetMenuAuthority (line 290) | func (menuService *MenuService) GetMenuAuthority(info *request.GetAuth...
method GetAuthoritiesByMenuId (line 318) | func (menuService *MenuService) GetAuthoritiesByMenuId(menuId uint) (a...
method GetDefaultRouterAuthorityIds (line 334) | func (menuService *MenuService) GetDefaultRouterAuthorityIds(menuId ui...
method SetMenuAuthorities (line 352) | func (menuService *MenuService) SetMenuAuthorities(menuId uint, author...
method UserAuthorityDefaultRouter (line 379) | func (menuService *MenuService) UserAuthorityDefaultRouter(user *syste...
FILE: server/service/system/sys_operation_record.go
type OperationRecordService (line 16) | type OperationRecordService struct
method DeleteSysOperationRecordByIds (line 27) | func (operationRecordService *OperationRecordService) DeleteSysOperati...
method DeleteSysOperationRecord (line 38) | func (operationRecordService *OperationRecordService) DeleteSysOperati...
method GetSysOperationRecord (line 49) | func (operationRecordService *OperationRecordService) GetSysOperationR...
method GetSysOperationRecordInfoList (line 61) | func (operationRecordService *OperationRecordService) GetSysOperationR...
FILE: server/service/system/sys_params.go
type SysParamsService (line 9) | type SysParamsService struct
method CreateSysParams (line 13) | func (sysParamsService *SysParamsService) CreateSysParams(sysParams *s...
method DeleteSysParams (line 20) | func (sysParamsService *SysParamsService) DeleteSysParams(ID string) (...
method DeleteSysParamsByIds (line 27) | func (sysParamsService *SysParamsService) DeleteSysParamsByIds(IDs []s...
method UpdateSysParams (line 34) | func (sysParamsService *SysParamsService) UpdateSysParams(sysParams sy...
method GetSysParams (line 41) | func (sysParamsService *SysParamsService) GetSysParams(ID string) (sys...
method GetSysParamsInfoList (line 48) | func (sysParamsService *SysParamsService) GetSysParamsInfoList(info sy...
method GetSysParam (line 79) | func (sysParamsService *SysParamsService) GetSysParam(key string) (par...
FILE: server/service/system/sys_skills.go
constant skillFileName (line 25) | skillFileName = "SKILL.md"
constant globalConstraintFileName (line 26) | globalConstraintFileName = "README.md"
constant defaultSkillMarkdown (line 47) | defaultSkillMarkdown = "## 技能用途\n请在这里描述技能的目标、适用场景与限制条件。\n\n## 输入\n- 请补充输...
constant defaultResourceMarkdown (line 49) | defaultResourceMarkdown = "# 资源说明\n请在这里补充资源内容。\n"
constant defaultReferenceMarkdown (line 51) | defaultReferenceMarkdown = "# 参考资料\n请在这里补充参考资料内容。\n"
constant defaultTemplateMarkdown (line 53) | defaultTemplateMarkdown = "# 模板\n请在这里补充模板内容。\n"
constant defaultGlobalConstraintMarkdown (line 55) | defaultGlobalConstraintMarkdown = "# 全局约束\n请在这里补充该工具的统一约束与使用规范。\n"
type SkillsService (line 57) | type SkillsService struct
method Tools (line 59) | func (s *SkillsService) Tools(_ context.Context) ([]system.SkillTool, ...
method List (line 70) | func (s *SkillsService) List(_ context.Context, tool string) ([]string...
method Detail (line 89) | func (s *SkillsService) Detail(_ context.Context, tool, skill string) ...
method Save (line 130) | func (s *SkillsService) Save(_ context.Context, req request.SkillSaveR...
method Delete (line 166) | func (s *SkillsService) Delete(_ context.Context, req request.SkillDel...
method Package (line 190) | func (s *SkillsService) Package(_ context.Context, req request.SkillPa...
method CreateScript (line 267) | func (s *SkillsService) CreateScript(_ context.Context, req request.Sk...
method GetScript (line 296) | func (s *SkillsService) GetScript(_ context.Context, req request.Skill...
method SaveScript (line 300) | func (s *SkillsService) SaveScript(_ context.Context, req request.Skil...
method CreateResource (line 304) | func (s *SkillsService) CreateResource(_ context.Context, req request....
method GetResource (line 308) | func (s *SkillsService) GetResource(_ context.Context, req request.Ski...
method SaveResource (line 312) | func (s *SkillsService) SaveResource(_ context.Context, req request.Sk...
method CreateReference (line 316) | func (s *SkillsService) CreateReference(_ context.Context, req request...
method GetReference (line 320) | func (s *SkillsService) GetReference(_ context.Context, req request.Sk...
method SaveReference (line 324) | func (s *SkillsService) SaveReference(_ context.Context, req request.S...
method CreateTemplate (line 328) | func (s *SkillsService) CreateTemplate(_ context.Context, req request....
method GetTemplate (line 332) | func (s *SkillsService) GetTemplate(_ context.Context, req request.Ski...
method SaveTemplate (line 336) | func (s *SkillsService) SaveTemplate(_ context.Context, req request.Sk...
method GetGlobalConstraint (line 340) | func (s *SkillsService) GetGlobalConstraint(_ context.Context, tool st...
method SaveGlobalConstraint (line 356) | func (s *SkillsService) SaveGlobalConstraint(_ context.Context, req re...
method DownloadOnlineSkill (line 388) | func (s *SkillsService) DownloadOnlineSkill(_ context.Context, req req...
method toolSkillsDir (line 518) | func (s *SkillsService) toolSkillsDir(tool string) (string, error) {
method skillDir (line 534) | func (s *SkillsService) skillDir(tool, skill string) (string, error) {
method ensureSkillDir (line 542) | func (s *SkillsService) ensureSkillDir(tool, skill string) (string, er...
method createMarkdownFile (line 556) | func (s *SkillsService) createMarkdownFile(tool, skill, subDir, fileNa...
method readSkillFile (line 585) | func (s *SkillsService) readSkillFile(tool, skill, subDir, fileName st...
method writeSkillFile (line 604) | func (s *SkillsService) writeSkillFile(tool, skill, subDir, fileName, ...
function extractZipToDir (line 467) | func extractZipToDir(zipPath, destDir string) error {
function parseSkillContent (line 622) | func parseSkillContent(content string) (system.SkillMeta, string, error) {
function buildSkillContent (line 647) | func buildSkillContent(meta system.SkillMeta, markdown string) (string, ...
function listFiles (line 663) | func listFiles(dir string) []string {
function isSafeName (line 678) | func isSafeName(name string) bool {
function isSafeFileName (line 691) | func isSafeFileName(name string) bool {
function buildScriptFileName (line 704) | func buildScriptFileName(fileName, scriptType string) (string, string, e...
function buildResourceFileName (line 729) | func buildResourceFileName(fileName string) (string, error) {
function scriptTemplate (line 744) | func scriptTemplate(lang string) string {
function copySkillDir (line 757) | func copySkillDir(src, dst string) error {
FILE: server/service/system/sys_system.go
type SystemConfigService (line 16) | type SystemConfigService struct
method GetSystemConfig (line 20) | func (systemConfigService *SystemConfigService) GetSystemConfig() (con...
method SetSystemConfig (line 31) | func (systemConfigService *SystemConfigService) SetSystemConfig(system...
method GetServerInfo (line 45) | func (systemConfigService *SystemConfigService) GetServerInfo() (serve...
FILE: server/service/system/sys_user.go
type UserService (line 24) | type UserService struct
method Register (line 28) | func (userService *UserService) Register(u system.SysUser) (userInter ...
method Login (line 47) | func (userService *UserService) Login(u *system.SysUser) (userInter *s...
method ChangePassword (line 69) | func (userService *UserService) ChangePassword(u *system.SysUser, newP...
method GetUserInfoList (line 89) | func (userService *UserService) GetUserInfoList(info systemReq.GetUser...
method SetUserAuthority (line 140) | func (userService *UserService) SetUserAuthority(id uint, authorityId ...
method SetUserAuthorities (line 189) | func (userService *UserService) SetUserAuthorities(adminAuthorityID, i...
method DeleteUser (line 230) | func (userService *UserService) DeleteUser(id int) (err error) {
method SetUserInfo (line 248) | func (userService *UserService) SetUserInfo(req system.SysUser) error {
method SetSelfInfo (line 268) | func (userService *UserService) SetSelfInfo(req system.SysUser) error {
method SetSelfSetting (line 280) | func (userService *UserService) SetSelfSetting(req common.JSONMap, uid...
method GetUserInfo (line 291) | func (userService *UserService) GetUserInfo(uuid uuid.UUID) (user syst...
method FindUserById (line 307) | func (userService *UserService) FindUserById(id int) (user *system.Sys...
method FindUserByUuid (line 319) | func (userService *UserService) FindUserByUuid(uuid string) (user *sys...
method ResetPassword (line 333) | func (userService *UserService) ResetPassword(ID uint, password string...
FILE: server/service/system/sys_version.go
type SysVersionService (line 11) | type SysVersionService struct
method CreateSysVersion (line 15) | func (sysVersionService *SysVersionService) CreateSysVersion(ctx conte...
method DeleteSysVersion (line 22) | func (sysVersionService *SysVersionService) DeleteSysVersion(ctx conte...
method DeleteSysVersionByIds (line 29) | func (sysVersionService *SysVersionService) DeleteSysVersionByIds(ctx ...
method GetSysVersion (line 36) | func (sysVersionService *SysVersionService) GetSysVersion(ctx context....
method GetSysVersionInfoList (line 43) | func (sysVersionService *SysVersionService) GetSysVersionInfoList(ctx ...
method GetSysVersionPublic (line 72) | func (sysVersionService *SysVersionService) GetSysVersionPublic(ctx co...
method GetMenusByIds (line 78) | func (sysVersionService *SysVersionService) GetMenusByIds(ctx context....
method GetApisByIds (line 84) | func (sysVersionService *SysVersionService) GetApisByIds(ctx context.C...
method GetDictionariesByIds (line 90) | func (sysVersionService *SysVersionService) GetDictionariesByIds(ctx c...
method ImportMenus (line 96) | func (sysVersionService *SysVersionService) ImportMenus(ctx context.Co...
method createMenusRecursively (line 104) | func (sysVersionService *SysVersionService) createMenusRecursively(tx ...
method ImportApis (line 178) | func (sysVersionService *SysVersionService) ImportApis(apis []system.S...
method ImportDictionaries (line 205) | func (sysVersionService *SysVersionService) ImportDictionaries(diction...
FILE: server/source/example/file_upload_download.go
constant initOrderExaFile (line 11) | initOrderExaFile = system.InitOrderInternal + 1
type initExaFileMysql (line 13) | type initExaFileMysql struct
method MigrateTable (line 20) | func (i *initExaFileMysql) MigrateTable(ctx context.Context) (context....
method TableCreated (line 28) | func (i *initExaFileMysql) TableCreated(ctx context.Context) bool {
method InitializerName (line 36) | func (i *initExaFileMysql) InitializerName() string {
method InitializeData (line 40) | func (i *initExaFileMysql) InitializeData(ctx context.Context) (contex...
method DataInserted (line 55) | func (i *initExaFileMysql) DataInserted(ctx context.Context) bool {
function init (line 16) | func init() {
FILE: server/source/system/api.go
type initApi (line 12) | type initApi struct
method InitializerName (line 21) | func (i *initApi) InitializerName() string {
method MigrateTable (line 25) | func (i *initApi) MigrateTable(ctx context.Context) (context.Context, ...
method TableCreated (line 33) | func (i *initApi) TableCreated(ctx context.Context) bool {
method InitializeData (line 41) | func (i *initApi) InitializeData(ctx context.Context) (context.Context...
method DataInserted (line 258) | func (i *initApi) DataInserted(ctx context.Context) bool {
constant initOrderApi (line 14) | initOrderApi = system.InitOrderSystem + 1
function init (line 17) | func init() {
FILE: server/source/system/api_ignore.go
type initApiIgnore (line 11) | type initApiIgnore struct
method InitializerName (line 20) | func (i *initApiIgnore) InitializerName() string {
method MigrateTable (line 24) | func (i *initApiIgnore) MigrateTable(ctx context.Context) (context.Con...
method TableCreated (line 32) | func (i *initApiIgnore) TableCreated(ctx context.Context) bool {
method InitializeData (line 40) | func (i *initApiIgnore) InitializeData(ctx context.Context) (context.C...
method DataInserted (line 67) | func (i *initApiIgnore) DataInserted(ctx context.Context) bool {
constant initOrderApiIgnore (line 13) | initOrderApiIgnore = initOrderApi + 1
function init (line 16) | func init() {
FILE: server/source/system/authorities_menus.go
constant initOrderMenuAuthority (line 12) | initOrderMenuAuthority = initOrderMenu + initOrderAuthority
type initMenuAuthority (line 14) | type initMenuAuthority struct
method MigrateTable (line 21) | func (i *initMenuAuthority) MigrateTable(ctx context.Context) (context...
method TableCreated (line 25) | func (i *initMenuAuthority) TableCreated(ctx context.Context) bool {
method InitializerName (line 29) | func (i *initMenuAuthority) InitializerName() string {
method InitializeData (line 33) | func (i *initMenuAuthority) InitializeData(ctx context.Context) (next ...
method DataInserted (line 107) | func (i *initMenuAuthority) DataInserted(ctx context.Context) bool {
function init (line 17) | func init() {
FILE: server/source/system/authority.go
constant initOrderAuthority (line 12) | initOrderAuthority = initOrderCasbin + 1
type initAuthority (line 14) | type initAuthority struct
method MigrateTable (line 21) | func (i *initAuthority) MigrateTable(ctx context.Context) (context.Con...
method TableCreated (line 29) | func (i *initAuthority) TableCreated(ctx context.Context) bool {
method InitializerName (line 37) | func (i *initAuthority) InitializerName() string {
method InitializeData (line 41) | func (i *initAuthority) InitializeData(ctx context.Context) (context.C...
method DataInserted (line 78) | func (i *initAuthority) DataInserted(ctx context.Context) bool {
function init (line 17) | func init() {
FILE: server/source/system/casbin.go
constant initOrderCasbin (line 12) | initOrderCasbin = initOrderApiIgnore + 1
type initCasbin (line 14) | type initCasbin struct
method MigrateTable (line 21) | func (i *initCasbin) MigrateTable(ctx context.Context) (context.Contex...
method TableCreated (line 29) | func (i *initCasbin) TableCreated(ctx context.Context) bool {
method InitializerName (line 37) | func (i *initCasbin) InitializerName() string {
method InitializeData (line 42) | func (i *initCasbin) InitializeData(ctx context.Context) (context.Cont...
method DataInserted (line 346) | func (i *initCasbin) DataInserted(ctx context.Context) bool {
function init (line 17) | func init() {
FILE: server/source/system/dictionary.go
constant initOrderDict (line 11) | initOrderDict = initOrderCasbin + 1
type initDict (line 13) | type initDict struct
method MigrateTable (line 20) | func (i *initDict) MigrateTable(ctx context.Context) (context.Context,...
method TableCreated (line 28) | func (i *initDict) TableCreated(ctx context.Context) bool {
method InitializerName (line 36) | func (i *initDict) InitializerName() string {
method InitializeData (line 40) | func (i *initDict) InitializeData(ctx context.Context) (next context.C...
method DataInserted (line 62) | func (i *initDict) DataInserted(ctx context.Context) bool {
function init (line 16) | func init() {
FILE: server/source/system/dictionary_detail.go
constant initOrderDictDetail (line 12) | initOrderDictDetail = initOrderDict + 1
type initDictDetail (line 14) | type initDictDetail struct
method MigrateTable (line 21) | func (i *initDictDetail) MigrateTable(ctx context.Context) (context.Co...
method TableCreated (line 29) | func (i *initDictDetail) TableCreated(ctx context.Context) bool {
method InitializerName (line 37) | func (i *initDictDetail) InitializerName() string {
method InitializeData (line 41) | func (i *initDictDetail) InitializeData(ctx context.Context) (context....
method DataInserted (line 110) | func (i *initDictDetail) DataInserted(ctx context.Context) bool {
function init (line 17) | func init() {
FILE: server/source/system/excel_template.go
type initExcelTemplate (line 11) | type initExcelTemplate struct
method InitializerName (line 20) | func (i *initExcelTemplate) InitializerName() string {
method MigrateTable (line 24) | func (i *initExcelTemplate) MigrateTable(ctx context.Context) (context...
method TableCreated (line 32) | func (i *initExcelTemplate) TableCreated(ctx context.Context) bool {
method InitializeData (line 40) | func (i *initExcelTemplate) InitializeData(ctx context.Context) (conte...
method DataInserted (line 66) | func (i *initExcelTemplate) DataInserted(ctx context.Context) bool {
constant initOrderExcelTemplate (line 13) | initOrderExcelTemplate = initOrderDictDetail + 1
function init (line 16) | func init() {
FILE: server/source/system/menu.go
constant initOrderMenu (line 12) | initOrderMenu = initOrderAuthority + 1
type initMenu (line 14) | type initMenu struct
method InitializerName (line 21) | func (i *initMenu) InitializerName() string {
method MigrateTable (line 25) | func (i *initMenu) MigrateTable(ctx context.Context) (context.Context,...
method TableCreated (line 37) | func (i *initMenu) TableCreated(ctx context.Context) bool {
method InitializeData (line 48) | func (i *initMenu) InitializeData(ctx context.Context) (next context.C...
method DataInserted (line 129) | func (i *initMenu) DataInserted(ctx context.Context) bool {
function init (line 17) | func init() {
FILE: server/source/system/user.go
constant initOrderUser (line 13) | initOrderUser = initOrderAuthority + 1
type initUser (line 15) | type initUser struct
method MigrateTable (line 22) | func (i *initUser) MigrateTable(ctx context.Context) (context.Context,...
method TableCreated (line 30) | func (i *initUser) TableCreated(ctx context.Context) bool {
method InitializerName (line 38) | func (i *initUser) InitializerName() string {
method InitializeData (line 42) | func (i *initUser) InitializeData(ctx context.Context) (next context.C...
method DataInserted (line 95) | func (i *initUser) DataInserted(ctx context.Context) bool {
function init (line 18) | func init() {
FILE: server/task/clearTable.go
function ClearTable (line 18) | func ClearTable(db *gorm.DB) error {
FILE: server/utils/ast/ast.go
function AddImport (line 13) | func AddImport(astNode ast.Node, imp string) {
function FindFunction (line 38) | func FindFunction(astNode ast.Node, FunctionName string) *ast.FuncDecl {
function FindArray (line 53) | func FindArray(astNode ast.Node, identName, selectorExprName string) *as...
function CreateMenuStructAst (line 76) | func CreateMenuStructAst(menus []system.SysBaseMenu) *[]ast.Expr {
function CreateApiStructAst (line 207) | func CreateApiStructAst(apis []system.SysApi) *[]ast.Expr {
function CheckImport (line 237) | func CheckImport(file *ast.File, importPath string) bool {
function clearPosition (line 250) | func clearPosition(astNode ast.Node) {
function CreateStmt (line 277) | func CreateStmt(statement string) *ast.ExprStmt {
function IsBlockStmt (line 286) | func IsBlockStmt(node ast.Node) bool {
function VariableExistsInBlock (line 291) | func VariableExistsInBlock(block *ast.BlockStmt, varName string) bool {
function CreateDictionaryStructAst (line 308) | func CreateDictionaryStructAst(dictionaries []system.SysDictionary) *[]a...
FILE: server/utils/ast/ast_auto_enter.go
function ImportForAutoEnter (line 13) | func ImportForAutoEnter(path string, funcName string, code string) {
FILE: server/utils/ast/ast_enter.go
type Visitor (line 17) | type Visitor struct
method Visit (line 24) | func (vi *Visitor) Visit(node ast.Node) ast.Visitor {
method addStruct (line 48) | func (vi *Visitor) addStruct(genDecl *ast.GenDecl) ast.Visitor {
method addImport (line 82) | func (vi *Visitor) addImport(genDecl *ast.GenDecl) ast.Visitor {
method addFuncBodyVar (line 103) | func (vi *Visitor) addFuncBodyVar(funDecl *ast.FuncDecl) ast.Visitor {
function ImportReference (line 154) | func ImportReference(filepath, importCode, structName, packageName, grou...
FILE: server/utils/ast/ast_gorm.go
function AddRegisterTablesAst (line 14) | func AddRegisterTablesAst(path, funcName, pk, varName, dbName, model str...
function addDBVar (line 40) | func addDBVar(astBody *ast.BlockStmt, varName, dbName string) {
function addAutoMigrate (line 85) | func addAutoMigrate(astBody *ast.BlockStmt, dbname string, pk string, mo...
function NeedAppendModel (line 151) | func NeedAppendModel(callNode ast.Node, pk string, model string) bool {
FILE: server/utils/ast/ast_init_test.go
function init (line 8) | func init() {
FILE: server/utils/ast/ast_rollback.go
function RollBackAst (line 15) | func RollBackAst(pk, model string) {
function RollGormBack (line 20) | func RollGormBack(pk, model string) {
function RollRouterBack (line 97) | func RollRouterBack(pk, model string) {
FILE: server/utils/ast/ast_router.go
function AppendNodeToList (line 14) | func AppendNodeToList(stmts []ast.Stmt, stmt ast.Stmt, index int) []ast....
function AddRouterCode (line 18) | func AddRouterCode(path, funcName, pk, model string) {
function needAppendRouter (line 95) | func needAppendRouter(funcNode ast.Node, pk string) (bool, *ast.BlockStm...
function needAppendInit (line 119) | func needAppendInit(funcNode ast.Node, routerName string, modelName stri...
FILE: server/utils/ast/ast_test.go
function TestAst (line 14) | func TestAst(t *testing.T) {
FILE: server/utils/ast/ast_type.go
type Type (line 3) | type Type
method String (line 5) | func (r Type) String() string {
method Group (line 9) | func (r Type) Group() string {
constant TypePackageApiEnter (line 35) | TypePackageApiEnter = "PackageApiEnter"
constant TypePackageRouterEnter (line 36) | TypePackageRouterEnter = "PackageRouterEnter"
constant TypePackageServiceEnter (line 37) | TypePackageServiceEnter = "PackageServiceEnter"
constant TypePackageApiModuleEnter (line 38) | TypePackageApiModuleEnter = "PackageApiModuleEnter"
constant TypePackageRouterModuleEnter (line 39) | TypePackageRouterModuleEnter = "PackageRouterModuleEnter"
constant TypePackageServiceModuleEnter (line 40) | TypePackageServiceModuleEnter = "PackageServiceModuleEnter"
constant TypePackageInitializeGorm (line 41) | TypePackageInitializeGorm = "PackageInitializeGorm"
constant TypePackageInitializeRouter (line 42) | TypePackageInitializeRouter = "PackageInitializeRouter"
constant TypePluginGen (line 43) | TypePluginGen = "PluginGen"
constant TypePluginApiEnter (line 44) | TypePluginApiEnter = "PluginApiEnter"
constant TypePluginInitializeV1 (line 45) | TypePluginInitializeV1 = "PluginInitializeV1"
constant TypePluginInitializeV2 (line 46) | TypePluginInitializeV2 = "PluginInitializeV2"
constant TypePluginRouterEnter (line 47) | TypePluginRouterEnter = "PluginRouterEnter"
constant TypePluginServiceEnter (line 48) | TypePluginServiceEnter = "PluginServiceEnter"
constant TypePluginInitializeApi (line 49) | TypePluginInitializeApi = "PluginInitializeApi"
constant TypePluginInitializeGorm (line 50) | TypePluginInitializeGorm = "PluginInitializeGorm"
constant TypePluginInitializeMenu (line 51) | TypePluginInitializeMenu = "PluginInitializeMenu"
constant TypePluginInitializeRouter (line 52) | TypePluginInitializeRouter = "PluginInitializeRouter"
FILE: server/utils/ast/extract_func.go
function ExtractFuncSourceByPosition (line 13) | func ExtractFuncSourceByPosition(filePath string, line int) (name string...
FILE: server/utils/ast/import.go
type Import (line 10) | type Import struct
method Parse (line 19) | func (a *Import) Parse(filename string, writer io.Writer) (file *ast.F...
method Rollback (line 23) | func (a *Import) Rollback(file *ast.File) error {
method Injection (line 48) | func (a *Import) Injection(file *ast.File) error {
method Format (line 92) | func (a *Import) Format(filename string, writer io.Writer, file *ast.F...
function NewImport (line 15) | func NewImport(importPath string) *Import {
FILE: server/utils/ast/interfaces.go
type Ast (line 8) | type Ast interface
FILE: server/utils/ast/interfaces_base.go
type Base (line 17) | type Base struct
method Parse (line 19) | func (a *Base) Parse(filename string, writer io.Writer) (file *ast.Fil...
method Rollback (line 32) | func (a *Base) Rollback(file *ast.File) error {
method Injection (line 36) | func (a *Base) Injection(file *ast.File) error {
method Format (line 40) | func (a *Base) Format(filename string, writer io.Writer, file *ast.Fil...
method RelativePath (line 58) | func (a *Base) RelativePath(filePath string) string {
method AbsolutePath (line 70) | func (a *Base) AbsolutePath(filePath string) string {
FILE: server/utils/ast/package_enter.go
type PackageEnter (line 10) | type PackageEnter struct
method Parse (line 21) | func (a *PackageEnter) Parse(filename string, writer io.Writer) (file ...
method Rollback (line 34) | func (a *PackageEnter) Rollback(file *ast.File) error {
method Injection (line 39) | func (a *PackageEnter) Injection(file *ast.File) error {
method Format (line 80) | func (a *PackageEnter) Format(filename string, writer io.Writer, file ...
FILE: server/utils/ast/package_enter_test.go
function TestPackageEnter_Rollback (line 9) | func TestPackageEnter_Rollback(t *testing.T) {
function TestPackageEnter_Injection (line 83) | func TestPackageEnter_Injection(t *testing.T) {
FILE: server/utils/ast/package_initialize_gorm.go
type PackageInitializeGorm (line 11) | type PackageInitializeGorm struct
method Parse (line 23) | func (a *PackageInitializeGorm) Parse(filename string, writer io.Write...
method Rollback (line 36) | func (a *PackageInitializeGorm) Rollback(file *ast.File) error {
method Injection (line 89) | func (a *PackageInitializeGorm) Injection(file *ast.File) error {
method Format (line 133) | func (a *PackageInitializeGorm) Format(filename string, writer io.Writ...
method addDbVar (line 141) | func (a *PackageInitializeGorm) addDbVar(astBody *ast.BlockStmt) {
FILE: server/utils/ast/package_initialize_gorm_test.go
function TestPackageInitializeGorm_Injection (line 9) | func TestPackageInitializeGorm_Injection(t *testing.T) {
function TestPackageInitializeGorm_Rollback (line 91) | func TestPackageInitializeGorm_Rollback(t *testing.T) {
FILE: server/utils/ast/package_initialize_router.go
type PackageInitializeRouter (line 13) | type PackageInitializeRouter struct
method Parse (line 29) | func (a *PackageInitializeRouter) Parse(filename string, writer io.Wri...
method Rollback (line 42) | func (a *PackageInitializeRouter) Rollback(file *ast.File) error {
method Injection (line 91) | func (a *PackageInitializeRouter) Injection(file *ast.File) error {
method Format (line 120) | func (a *PackageInitializeRouter) Format(filename string, writer io.Wr...
method CreateAssignStmt (line 127) | func (a *PackageInitializeRouter) CreateAssignStmt() *ast.AssignStmt {
FILE: server/utils/ast/package_initialize_router_test.go
function TestPackageInitializeRouter_Injection (line 9) | func TestPackageInitializeRouter_Injection(t *testing.T) {
function TestPackageInitializeRouter_Rollback (line 85) | func TestPackageInitializeRouter_Rollback(t *testing.T) {
FILE: server/utils/ast/package_module_enter.go
type PackageModuleEnter (line 11) | type PackageModuleEnter struct
method Parse (line 25) | func (a *PackageModuleEnter) Parse(filename string, writer io.Writer) ...
method Rollback (line 38) | func (a *PackageModuleEnter) Rollback(file *ast.File) error {
method Injection (line 82) | func (a *PackageModuleEnter) Injection(file *ast.File) error {
method Format (line 175) | func (a *PackageModuleEnter) Format(filename string, writer io.Writer,...
FILE: server/utils/ast/package_module_enter_test.go
function TestPackageModuleEnter_Rollback (line 9) | func TestPackageModuleEnter_Rollback(t *testing.T) {
function TestPackageModuleEnter_Injection (line 98) | func TestPackageModuleEnter_Injection(t *testing.T) {
FILE: server/utils/ast/plugin_enter.go
type PluginEnter (line 11) | type PluginEnter struct
method Parse (line 25) | func (a *PluginEnter) Parse(filename string, writer io.Writer) (file *...
method Rollback (line 38) | func (a *PluginEnter) Rollback(file *ast.File) error {
method Injection (line 87) | func (a *PluginEnter) Injection(file *ast.File) error {
method Format (line 162) | func (a *PluginEnter) Format(filename string, writer io.Writer, file *...
FILE: server/utils/ast/plugin_enter_test.go
function TestPluginEnter_Injection (line 9) | func TestPluginEnter_Injection(t *testing.T) {
function TestPluginEnter_Rollback (line 113) | func TestPluginEnter_Rollback(t *testing.T) {
FILE: server/utils/ast/plugin_gen.go
type PluginGen (line 9) | type PluginGen struct
method Parse (line 20) | func (a *PluginGen) Parse(filename string, writer io.Writer) (file *as...
method Rollback (line 32) | func (a *PluginGen) Rollback(file *ast.File) error {
method Injection (line 97) | func (a *PluginGen) Injection(file *ast.File) error {
method Format (line 184) | func (a *PluginGen) Format(filename string, writer io.Writer, file *as...
FILE: server/utils/ast/plugin_gen_test.go
function TestPluginGenModel_Injection (line 9) | func TestPluginGenModel_Injection(t *testing.T) {
function TestPluginGenModel_Rollback (line 69) | func TestPluginGenModel_Rollback(t *testing.T) {
FILE: server/utils/ast/plugin_initialize_gorm.go
type PluginInitializeGorm (line 8) | type PluginInitializeGorm struct
method Parse (line 19) | func (a *PluginInitializeGorm) Parse(filename string, writer io.Writer...
method Rollback (line 32) | func (a *PluginInitializeGorm) Rollback(file *ast.File) error {
method Injection (line 77) | func (a *PluginInitializeGorm) Injection(file *ast.File) error {
method Format (line 106) | func (a *PluginInitializeGorm) Format(filename string, writer io.Write...
FILE: server/utils/ast/plugin_initialize_gorm_test.go
function TestPluginInitializeGorm_Injection (line 9) | func TestPluginInitializeGorm_Injection(t *testing.T) {
function TestPluginInitializeGorm_Rollback (line 80) | func TestPluginInitializeGorm_Rollback(t *testing.T) {
FILE: server/utils/ast/plugin_initialize_router.go
type PluginInitializeRouter (line 11) | type PluginInitializeRouter struct
method Parse (line 27) | func (a *PluginInitializeRouter) Parse(filename string, writer io.Writ...
method Rollback (line 40) | func (a *PluginInitializeRouter) Rollback(file *ast.File) error {
method Injection (line 86) | func (a *PluginInitializeRouter) Injection(file *ast.File) error {
method Format (line 119) | func (a *PluginInitializeRouter) Format(filename string, writer io.Wri...
FILE: server/utils/ast/plugin_initialize_router_test.go
function TestPluginInitializeRouter_Injection (line 9) | func TestPluginInitializeRouter_Injection(t *testing.T) {
function TestPluginInitializeRouter_Rollback (line 83) | func TestPluginInitializeRouter_Rollback(t *testing.T) {
FILE: server/utils/ast/plugin_initialize_v2.go
type PluginInitializeV2 (line 11) | type PluginInitializeV2 struct
method Parse (line 22) | func (a *PluginInitializeV2) Parse(filename string, writer io.Writer) ...
method Injection (line 35) | func (a *PluginInitializeV2) Injection(file *ast.File) error {
method Rollback (line 73) | func (a *PluginInitializeV2) Rollback(file *ast.File) error {
method Format (line 77) | func (a *PluginInitializeV2) Format(filename string, writer io.Writer,...
FILE: server/utils/ast/plugin_initialize_v2_test.go
function TestPluginInitialize_Injection (line 9) | func TestPluginInitialize_Injection(t *testing.T) {
function TestPluginInitialize_Rollback (line 53) | func TestPluginInitialize_Rollback(t *testing.T) {
FILE: server/utils/autocode/template_funcs.go
function GetTemplateFuncMap (line 12) | func GetTemplateFuncMap() template.FuncMap {
function GenerateField (line 27) | func GenerateField(field systemReq.AutoCodeField) string {
function GenerateSearchConditions (line 125) | func GenerateSearchConditions(fields []*systemReq.AutoCodeField) string {
function GenerateSearchFormItem (line 202) | func GenerateSearchFormItem(field systemReq.AutoCodeField) string {
function GenerateTableColumn (line 284) | func GenerateTableColumn(field systemReq.AutoCodeField) string {
function GenerateFormItem (line 458) | func GenerateFormItem(field systemReq.AutoCodeField) string {
function GenerateDescriptionItem (line 579) | func GenerateDescriptionItem(field systemReq.AutoCodeField) string {
function GenerateDefaultFormValue (line 645) | func GenerateDefaultFormValue(field systemReq.AutoCodeField) string {
function GenerateSearchField (line 679) | func GenerateSearchField(field systemReq.AutoCodeField) string {
FILE: server/utils/breakpoint_continue.go
constant breakpointDir (line 16) | breakpointDir = "./breakpointDir/"
constant finishDir (line 17) | finishDir = "./fileDir/"
function BreakPointContinue (line 26) | func BreakPointContinue(content []byte, fileName string, contentNumber i...
function CheckMd5 (line 45) | func CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
function makeFileContent (line 60) | func makeFileContent(content []byte, fileName string, FileDir string, co...
function MakeFile (line 84) | func MakeFile(fileName string, FileMd5 string) (string, error) {
function RemoveChunk (line 115) | func RemoveChunk(FileMd5 string) error {
FILE: server/utils/captcha/redis.go
function NewDefaultRedisStore (line 11) | func NewDefaultRedisStore() *RedisStore {
type RedisStore (line 19) | type RedisStore struct
method UseWithCtx (line 25) | func (rs *RedisStore) UseWithCtx(ctx context.Context) *RedisStore {
method Set (line 32) | func (rs *RedisStore) Set(id string, value string) error {
method Get (line 41) | func (rs *RedisStore) Get(key string, clear bool) string {
method Verify (line 57) | func (rs *RedisStore) Verify(id, answer string, clear bool) bool {
FILE: server/utils/casbin_util.go
function GetCasbin (line 19) | func GetCasbin() *casbin.SyncedCachedEnforcer {
FILE: server/utils/claims.go
function ClearToken (line 14) | func ClearToken(c *gin.Context) {
function SetToken (line 28) | func SetToken(c *gin.Context, token string, maxAge int) {
function GetToken (line 42) | func GetToken(c *gin.Context) string {
function GetClaims (line 57) | func GetClaims(c *gin.Context) (*systemReq.CustomClaims, error) {
function GetUserID (line 68) | func GetUserID(c *gin.Context) uint {
function GetUserUuid (line 82) | func GetUserUuid(c *gin.Context) uuid.UUID {
function GetUserAuthorityId (line 96) | func GetUserAuthorityId(c *gin.Context) uint {
function GetUserInfo (line 110) | func GetUserInfo(c *gin.Context) *systemReq.CustomClaims {
function GetUserName (line 124) | func GetUserName(c *gin.Context) string {
function LoginToken (line 137) | func LoginToken(user system.Login) (token string, claims systemReq.Custo...
FILE: server/utils/directory.go
function PathExists (line 20) | func PathExists(path string) (bool, error) {
function CreateDir (line 40) | func CreateDir(dirs ...string) (err error) {
function FileMove (line 63) | func FileMove(src string, dst string) (err error) {
function DeLFile (line 92) | func DeLFile(filePath string) error {
function TrimSpace (line 102) | func TrimSpace(target interface{}) {
function FileExist (line 118) | func FileExist(path string) bool {
FILE: server/utils/fmt_plus.go
function StructToMap (line 17) | func StructToMap(obj interface{}) map[string]interface{} {
function ArrayToString (line 38) | func ArrayToString(array []interface{}) string {
function Pointer (line 42) | func Pointer[T any](in T) (out *T) {
function FirstUpper (line 46) | func FirstUpper(s string) string {
function FirstLower (line 53) | func FirstLower(s string) string {
function MaheHump (line 61) | func MaheHump(s string) string {
function HumpToUnderscore (line 72) | func HumpToUnderscore(s string) string {
function RandomString (line 89) | func RandomString(n int) string {
function RandomInt (line 98) | func RandomInt(min, max int) int {
function BuildTree (line 103) | func BuildTree[T common.TreeNode[T]](nodes []T) []T {
FILE: server/utils/hash.go
function BcryptHash (line 10) | func BcryptHash(password string) string {
function BcryptCheck (line 16) | func BcryptCheck(password, hash string) bool {
function MD5V (line 27) | func MD5V(str []byte, b ...byte) string {
FILE: server/utils/human_duration.go
function ParseDuration (line 9) | func ParseDuration(d string) (time.Duration, error) {
FILE: server/utils/human_duration_test.go
function TestParseDuration (line 8) | func TestParseDuration(t *testing.T) {
FILE: server/utils/json.go
function GetJSONKeys (line 8) | func GetJSONKeys(jsonStr string) (keys []string, err error) {
FILE: server/utils/json_test.go
function TestGetJSONKeys (line 8) | func TestGetJSONKeys(t *testing.T) {
FILE: server/utils/jwt.go
type JWT (line 13) | type JWT struct
method CreateClaims (line 32) | func (j *JWT) CreateClaims(baseClaims request.BaseClaims) request.Cust...
method CreateToken (line 49) | func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
method CreateTokenByOldToken (line 55) | func (j *JWT) CreateTokenByOldToken(oldToken string, claims request.Cu...
method ParseToken (line 63) | func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, e...
function NewJWT (line 26) | func NewJWT() *JWT {
function SetRedisJWT (line 96) | func SetRedisJWT(jwt string, userName string) (err error) {
FILE: server/utils/plugin/plugin.go
constant OnlyFuncName (line 8) | OnlyFuncName = "Plugin"
type Plugin (line 12) | type Plugin interface
FILE: server/utils/plugin/v2/plugin.go
type Plugin (line 8) | type Plugin interface
FILE: server/utils/plugin/v2/registry.go
function Register (line 11) | func Register(p Plugin) {
function Registered (line 21) | func Registered() []Plugin {
FILE: server/utils/request/http.go
function HttpRequest (line 10) | func HttpRequest(
FILE: server/utils/server.go
constant B (line 14) | B = 1
constant KB (line 15) | KB = 1024 * B
constant MB (line 16) | MB = 1024 * KB
constant GB (line 17) | GB = 1024 * MB
type Server (line 20) | type Server struct
type Os (line 27) | type Os struct
type Cpu (line 35) | type Cpu struct
type Ram (line 40) | type Ram struct
type Disk (line 46) | type Disk struct
function InitOS (line 60) | func InitOS() (o Os) {
function InitCPU (line 74) | func InitCPU() (c Cpu, err error) {
function InitRAM (line 93) | func InitRAM() (r Ram, err error) {
function InitDisk (line 109) | func InitDisk() (d []Disk, err error) {
FILE: server/utils/stacktrace/stacktrace.go
type Frame (line 10) | type Frame struct
function FindFinalCaller (line 20) | func FindFinalCaller(stack string) (Frame, bool) {
function shouldSkip (line 47) | func shouldSkip(file string) bool {
FILE: server/utils/system_events.go
type SystemEvents (line 8) | type SystemEvents struct
method RegisterReloadHandler (line 17) | func (e *SystemEvents) RegisterReloadHandler(handler func() error) {
method TriggerReload (line 24) | func (e *SystemEvents) TriggerReload() error {
FILE: server/utils/timer/timed_task.go
type Timer (line 8) | type Timer interface
type task (line 37) | type task struct
type taskManager (line 43) | type taskManager struct
type timer (line 49) | type timer struct
method AddTaskByFunc (line 55) | func (t *timer) AddTaskByFunc(cronName string, spec string, fun func()...
method AddTaskByFuncWithSecond (line 76) | func (t *timer) AddTaskByFuncWithSecond(cronName string, spec string, ...
method AddTaskByJob (line 98) | func (t *timer) AddTaskByJob(cronName string, spec string, job interfa...
method AddTaskByJobWithSeconds (line 119) | func (t *timer) AddTaskByJobWithSeconds(cronName string, spec string, ...
method FindCron (line 141) | func (t *timer) FindCron(cronName string) (*taskManager, bool) {
method FindTask (line 149) | func (t *timer) FindTask(cronName string, taskName string) (*task, boo...
method FindCronList (line 165) | func (t *timer) FindCronList() map[string]*taskManager {
method StartCron (line 172) | func (t *timer) StartCron(cronName string) {
method StopCron (line 181) | func (t *timer) StopCron(cronName string) {
method RemoveTask (line 190) | func (t *timer) RemoveTask(cronName string, id int) {
method RemoveTaskByName (line 200) | func (t *timer) RemoveTaskByName(cronName string, taskName string) {
method Clear (line 209) | func (t *timer) Clear(cronName string) {
method Close (line 219) | func (t *timer) Close() {
function NewTimerTask (line 227) | func NewTimerTask() Timer {
FILE: server/utils/timer/timed_task_test.go
type mockJob (line 13) | type mockJob struct
method Run (line 15) | func (job mockJob) Run() {
function mockFunc (line 19) | func mockFunc() {
function TestNewTimerTask (line 24) | func TestNewTimerTask(t *testing.T) {
FILE: server/utils/upload/aliyun_oss.go
type AliyunOSS (line 13) | type AliyunOSS struct
method UploadFile (line 15) | func (*AliyunOSS) UploadFile(file *multipart.FileHeader) (string, stri...
method DeleteFile (line 43) | func (*AliyunOSS) DeleteFile(key string) error {
function NewBucket (line 61) | func NewBucket() (*oss.Bucket, error) {
FILE: server/utils/upload/aws_s3.go
type AwsS3 (line 20) | type AwsS3 struct
method UploadFile (line 29) | func (*AwsS3) UploadFile(file *multipart.FileHeader) (string, string, ...
method DeleteFile (line 63) | func (*AwsS3) DeleteFile(key string) error {
function newS3Client (line 88) | func newS3Client() *s3.Client {
FILE: server/utils/upload/cloudflare_r2.go
type CloudflareR2 (line 19) | type CloudflareR2 struct
method UploadFile (line 21) | func (c *CloudflareR2) UploadFile(file *multipart.FileHeader) (fileUrl...
method DeleteFile (line 47) | func (c *CloudflareR2) DeleteFile(key string) error {
method newR2Client (line 70) | func (*CloudflareR2) newR2Client() *s3.Client {
FILE: server/utils/upload/local.go
type Local (line 20) | type Local struct
method UploadFile (line 31) | func (*Local) UploadFile(file *multipart.FileHeader) (string, string, ...
method DeleteFile (line 81) | func (*Local) DeleteFile(key string) error {
FILE: server/utils/upload/minio_oss.go
type Minio (line 23) | type Minio struct
method UploadFile (line 55) | func (m *Minio) UploadFile(file *multipart.FileHeader) (filePathres, k...
method DeleteFile (line 99) | func (m *Minio) DeleteFile(key string) error {
function GetMinio (line 28) | func GetMinio(endpoint, accessKeyID, secretAccessKey, bucketName string,...
FILE: server/utils/upload/obs.go
type Obs (line 13) | type Obs struct
method UploadFile (line 19) | func (o *Obs) UploadFile(file *multipart.FileHeader) (string, string, ...
method DeleteFile (line 54) | func (o *Obs) DeleteFile(key string) error {
function NewHuaWeiObsClient (line 15) | func NewHuaWeiObsClient() (client *obs.ObsClient, err error) {
FILE: server/utils/upload/qiniu.go
type Qiniu (line 16) | type Qiniu struct
method UploadFile (line 27) | func (*Qiniu) UploadFile(file *multipart.FileHeader) (string, string, ...
method DeleteFile (line 61) | func (*Qiniu) DeleteFile(key string) error {
function qiniuConfig (line 78) | func qiniuConfig() *storage.Config {
FILE: server/utils/upload/tencent_cos.go
type TencentCOS (line 18) | type TencentCOS struct
method UploadFile (line 21) | func (*TencentCOS) UploadFile(file *multipart.FileHeader) (string, str...
method DeleteFile (line 39) | func (*TencentCOS) DeleteFile(key string) error {
function NewClient (line 51) | func NewClient() *cos.Client {
FILE: server/utils/upload/upload.go
type OSS (line 12) | type OSS interface
function NewOss (line 20) | func NewOss() OSS {
FILE: server/utils/validator.go
type Rules (line 11) | type Rules
type RulesMap (line 13) | type RulesMap
function RegisterRule (line 23) | func RegisterRule(key string, rule Rules) (err error) {
function NotEmpty (line 37) | func NotEmpty() string {
function RegexpMatch (line 47) | func RegexpMatch(rule string) string {
function Lt (line 57) | func Lt(mark string) string {
function Le (line 67) | func Le(mark string) string {
function Eq (line 77) | func Eq(mark string) string {
function Ne (line 87) | func Ne(mark string) string {
function Ge (line 97) | func Ge(mark string) string {
function Gt (line 107) | func Gt(mark string) string {
function Verify (line 118) | func Verify(st interface{}, roleMap Rules) (err error) {
function compareVerify (line 173) | func compareVerify(value reflect.Value, VerifyStr string) bool {
function isBlank (line 196) | func isBlank(value reflect.Value) bool {
function compare (line 220) | func compare(value interface{}, VerifyStr string) bool {
function regexpMatch (line 292) | func regexpMatch(rule, matchStr string) bool {
FILE: server/utils/validator_test.go
type PageInfoTest (line 8) | type PageInfoTest struct
function TestVerify (line 13) | func TestVerify(t *testing.T) {
FILE: server/utils/zip.go
function Unzip (line 13) | func Unzip(zipFile string, destDir string) ([]string, error) {
FILE: web/limit.js
function replaceStr (line 21) | function replaceStr(filePath, sourceRegx, targetSrt) {
FILE: web/src/api/github.js
function Commits (line 5) | function Commits(page) {
function Members (line 14) | function Members() {
FILE: web/src/core/error-handel.js
function sendErrorTip (line 3) | function sendErrorTip(errorInfo) {
FILE: web/src/core/global.js
method render (line 11) | render() {
FILE: web/src/directive/clickOutSide.js
method mounted (line 4) | mounted(el, binding) {
method unmounted (line 33) | unmounted(el) {
FILE: web/src/hooks/charts.js
function useChartOption (line 7) | function useChartOption(sourceOption) {
FILE: web/src/hooks/responsive.js
constant WIDTH (line 9) | const WIDTH = 992
function queryDevice (line 11) | function queryDevice() {
function useResponsive (line 16) | function useResponsive(immediate) {
FILE: web/src/permission.js
constant WHITE_LIST (line 16) | const WHITE_LIST = ['Login', 'Init']
function isExternalUrl (line 18) | function isExternalUrl(val) {
function normalizeAbsolutePath (line 23) | function normalizeAbsolutePath(p) {
function normalizeRelativePath (line 28) | function normalizeRelativePath(p) {
function addTopLevelIfAbsent (line 33) | function addTopLevelIfAbsent(r) {
function addRouteByChildren (line 42) | function addRouteByChildren(route, segments = [], parentName = null) {
FILE: web/src/utils/asyncRouter.js
function dynamicImport (line 20) | function dynamicImport(dynamicViewsModules, component) {
FILE: web/src/utils/date.js
function formatTimeToStr (line 38) | function formatTimeToStr(times, pattern) {
FILE: web/src/utils/event.js
function addEventListen (line 1) | function addEventListen(target, event, handler, capture = false) {
function removeEventListen (line 10) | function removeEventListen(target, event, handler, capture = false) {
FILE: web/src/utils/format.js
function addOpacityToColor (line 135) | function addOpacityToColor(u, opacity) {
FILE: web/src/utils/image.js
class ImageCompress (line 1) | class ImageCompress {
method constructor (line 2) | constructor(file, fileSize, maxWH = 1920) {
method compress (line 8) | compress() {
method dWH (line 50) | dWH(srcW, srcH, dMax) {
method fileSizeKB (line 70) | fileSizeKB(dataURL) {
method dataURLtoBlob (line 79) | dataURLtoBlob(dataURL, fileType) {
constant VIDEO_EXTENSIONS (line 109) | const VIDEO_EXTENSIONS = ['.mp4', '.mov', '.webm', '.ogg']
constant VIDEO_MIME_TYPES (line 110) | const VIDEO_MIME_TYPES = ['video/mp4', 'video/webm', 'video/ogg']
constant IMAGE_MIME_TYPES (line 111) | const IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'imag...
FILE: web/src/utils/page.js
function getPageTitle (line 3) | function getPageTitle(pageTitle, route) {
FILE: web/src/utils/request.js
function getErrorMessage (line 126) | function getErrorMessage(error) {
FILE: web/vitePlugin/componentName/index.js
method configResolved (line 71) | configResolved(resolvedConfig) {
method buildStart (line 77) | buildStart() {
method buildEnd (line 80) | buildEnd() {
FILE: web/vitePlugin/secret/index.js
function AddSecret (line 1) | function AddSecret(secret) {
Condensed preview — 646 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,379K chars).
[
{
"path": ".aone_copilot/rules/project_rules.md",
"chars": 21896,
"preview": "### 功能描述以及必要性描述\n\n---\nname: gin-vue-admin\ndescription: |\n gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。\n \n 前端技术栈:\n - Vue 3.5.7 "
},
{
"path": ".claude/rules/project_rules.md",
"chars": 21896,
"preview": "### 功能描述以及必要性描述\n\n---\nname: gin-vue-admin\ndescription: |\n gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。\n \n 前端技术栈:\n - Vue 3.5.7 "
},
{
"path": ".codex/rules/project_rules.md",
"chars": 21896,
"preview": "### 功能描述以及必要性描述\n\n---\nname: gin-vue-admin\ndescription: |\n gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。\n \n 前端技术栈:\n - Vue 3.5.7 "
},
{
"path": ".cursor/rules/project_rules.md",
"chars": 21896,
"preview": "### 功能描述以及必要性描述\n\n---\nname: gin-vue-admin\ndescription: |\n gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。\n \n 前端技术栈:\n - Vue 3.5.7 "
},
{
"path": ".gitattributes",
"chars": 55,
"preview": "*.sql linguist-language=GO\n*.html linguist-language=GO\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 646,
"preview": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [u"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yaml",
"chars": 1215,
"preview": "name: 🐛 Bug report\ndescription: Report a bug to help us improve Gin-Vue-Admin\ntitle: \"[Bug]: \"\nlabels: [bug]\nassignees:\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 196,
"preview": "blank_issues_enabled: false\ncontact_links:\n - name: Document\n url: https://www.gin-vue-admin.com\n about: If you h"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.yaml",
"chars": 455,
"preview": "name: 🚀 Feature request\ndescription: Suggest an idea for Gin-Vue-Admin\ntitle: \"[Feature]: \"\nlabels: [feature]\nassignees:"
},
{
"path": ".github/workflows/ci.yaml",
"chars": 10063,
"preview": "name: CI\n\non:\n push:\n branches: [ '*' ]\n pull_request:\n release:\n types: [ created, edited ]\n workflow_dispatc"
},
{
"path": ".gitignore",
"chars": 468,
"preview": "/web/node_modules\n/web/dist\n\n.DS_Store\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug"
},
{
"path": ".trae/rules/project_rules.md",
"chars": 21896,
"preview": "### 功能描述以及必要性描述\n\n---\nname: gin-vue-admin\ndescription: |\n gin-vue-admin 是一个基于现代化技术栈的全栈管理系统框架。\n \n 前端技术栈:\n - Vue 3.5.7 "
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3348,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 893,
"preview": "\n### Contributing Guide\n#### 1 Issue Guidelines\n\n- Issues are exclusively for bug reports, feature requests and design-r"
},
{
"path": "LICENSE",
"chars": 11345,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 2836,
"preview": "SHELL = /bin/bash\n\n#SCRIPT_DIR = $(shell pwd)/etc/script\n#请选择golang版本\nBUILD_IMAGE_SERVER = golang:1.22\n#请选择node"
},
{
"path": "README-en.md",
"chars": 13146,
"preview": "\n<div align=center>\n<img src=\"http://qmplusimg.henrongyi.top/gvalogo.jpg\" width=\"300\" height=\"300\" />\n</div>\n<div align="
},
{
"path": "README.md",
"chars": 13540,
"preview": "\n<div align=center>\n<img src=\"http://qmplusimg.henrongyi.top/gvalogo.jpg\" width=\"300\" height=\"300\" />\n</div>\n\n<div align"
},
{
"path": "SECURITY.md",
"chars": 110,
"preview": "# Security Policy\n\n## Reporting a Vulnerability\n\nPlease report security issues to qimiaojiangjizhao@gmail.com\n"
},
{
"path": "deploy/docker/Dockerfile",
"chars": 866,
"preview": "FROM centos:7\nWORKDIR /opt\nENV LANG=en_US.utf8\nCOPY deploy/docker/entrypoint.sh .\nCOPY build/ /usr/share/nginx/html/\nCOP"
},
{
"path": "deploy/docker/entrypoint.sh",
"chars": 624,
"preview": "#!/bin/bash\nif [ ! -d \"/var/lib/mysql/gva\" ]; then\n mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysq"
},
{
"path": "deploy/docker-compose/docker-compose.yaml",
"chars": 2032,
"preview": "version: \"3\"\n\n# 声明一个名为network的networks,subnet为network的子网地址,默认网关是177.7.0.1\nnetworks:\n network:\n ipam:\n driver: d"
},
{
"path": "deploy/kubernetes/server/gva-server-configmap.yaml",
"chars": 3889,
"preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: config.yaml\n annotations:\n flipped-aurora/gin-vue-admin: backend\n "
},
{
"path": "deploy/kubernetes/server/gva-server-deployment.yaml",
"chars": 1984,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: gva-server\n annotations:\n flipped-aurora/gin-vue-admin: backe"
},
{
"path": "deploy/kubernetes/server/gva-server-service.yaml",
"chars": 432,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: gva-server\n annotations:\n flipped-aurora/gin-vue-admin: backend\n g"
},
{
"path": "deploy/kubernetes/web/gva-web-configmap.yaml",
"chars": 959,
"preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: my.conf\ndata:\n my.conf: |\n server {\n listen 8080;\n "
},
{
"path": "deploy/kubernetes/web/gva-web-deploymemt.yaml",
"chars": 1260,
"preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: gva-web\n annotations:\n flipped-aurora/gin-vue-admin: ui\n g"
},
{
"path": "deploy/kubernetes/web/gva-web-ingress.yaml",
"chars": 351,
"preview": "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: gva-ingress\n annotations:\n kubernetes.io/ingress.cl"
},
{
"path": "deploy/kubernetes/web/gva-web-service.yaml",
"chars": 418,
"preview": "apiVersion: v1\nkind: Service\nmetadata:\n name: gva-web\n annotations:\n flipped-aurora/gin-vue-admin: ui\n github: \""
},
{
"path": "gin-vue-admin.code-workspace",
"chars": 970,
"preview": "{\n \"folders\": [\n {\n \"path\": \"server\",\n \"name\": \"backend\"\n },\n {\n \"path\": \"web\",\n \"name\": \""
},
{
"path": "server/Dockerfile",
"chars": 1140,
"preview": "FROM golang:alpine as builder\n\nWORKDIR /go/src/github.com/flipped-aurora/gin-vue-admin/server\nCOPY . .\n\nRUN go env -w GO"
},
{
"path": "server/README.md",
"chars": 1689,
"preview": "## server项目结构\n\n```shell\n├── api\n│ └── v1\n├── config\n├── core\n├── docs\n├── global\n├── initialize\n│ └── internal\n├── m"
},
{
"path": "server/api/v1/enter.go",
"chars": 278,
"preview": "package v1\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/api/v1/example\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/api/v1/example/enter.go",
"chars": 477,
"preview": "package example\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/service\"\n\ntype ApiGroup struct {\n\tCustomerApi\n\tF"
},
{
"path": "server/api/v1/example/exa_attachment_category.go",
"chars": 2571,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tcommon \"github.com/flipped-aurora/gi"
},
{
"path": "server/api/v1/example/exa_breakpoint_continue.go",
"chars": 5435,
"preview": "package example\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"mime/multipart\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/flipped-aurora/gin-vue-admi"
},
{
"path": "server/api/v1/example/exa_customer.go",
"chars": 5498,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-a"
},
{
"path": "server/api/v1/example/exa_file_upload_download.go",
"chars": 4573,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-a"
},
{
"path": "server/api/v1/system/auto_code_history.go",
"chars": 3531,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tcommon \"github.com/flipped-aurora/gin"
},
{
"path": "server/api/v1/system/auto_code_mcp.go",
"chars": 4127,
"preview": "package system\n\nimport (\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin"
},
{
"path": "server/api/v1/system/auto_code_package.go",
"chars": 3446,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tcommon \"github.com/flipped-aurora/gin"
},
{
"path": "server/api/v1/system/auto_code_plugin.go",
"chars": 6361,
"preview": "package system\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"githu"
},
{
"path": "server/api/v1/system/auto_code_template.go",
"chars": 3522,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/enter.go",
"chars": 2543,
"preview": "package system\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/service\"\n\ntype ApiGroup struct {\n\tDBApi\n\tJwtApi\n\t"
},
{
"path": "server/api/v1/system/sys_api.go",
"chars": 11251,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_api_token.go",
"chars": 2096,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_authority.go",
"chars": 8629,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_authority_btn.go",
"chars": 2494,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_auto_code.go",
"chars": 3439,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common\"\n\n\t\"github.com/flipped-aurora/gin"
},
{
"path": "server/api/v1/system/sys_captcha.go",
"chars": 2031,
"preview": "package system\n\nimport (\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/g"
},
{
"path": "server/api/v1/system/sys_casbin.go",
"chars": 2319,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_dictionary.go",
"chars": 6442,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_dictionary_detail.go",
"chars": 9162,
"preview": "package system\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-auror"
},
{
"path": "server/api/v1/system/sys_error.go",
"chars": 5609,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_export_template.go",
"chars": 13681,
"preview": "package system\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server"
},
{
"path": "server/api/v1/system/sys_initdb.go",
"chars": 1606,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_jwt_blacklist.go",
"chars": 946,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_login_log.go",
"chars": 2206,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_menu.go",
"chars": 10891,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_operation_record.go",
"chars": 4487,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_params.go",
"chars": 5192,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_skills.go",
"chars": 8148,
"preview": "package system\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-auro"
},
{
"path": "server/api/v1/system/sys_system.go",
"chars": 2756,
"preview": "package system\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-ad"
},
{
"path": "server/api/v1/system/sys_user.go",
"chars": 15922,
"preview": "package system\n\nimport (\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipp"
},
{
"path": "server/api/v1/system/sys_version.go",
"chars": 13720,
"preview": "package system\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sort\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin"
},
{
"path": "server/config/auto_code.go",
"chars": 571,
"preview": "package config\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n)\n\ntype Autocode struct {\n\tWeb string `mapstructure:\"web\" json:\""
},
{
"path": "server/config/captcha.go",
"chars": 735,
"preview": "package config\n\ntype Captcha struct {\n\tKeyLong int `mapstructure:\"key-long\" json:\"key-long\" yaml:\"key-long\"` "
},
{
"path": "server/config/config.go",
"chars": 2110,
"preview": "package config\n\ntype Server struct {\n\tJWT JWT `mapstructure:\"jwt\" json:\"jwt\" yaml:\"jwt\"`\n\tZap Zap `m"
},
{
"path": "server/config/cors.go",
"chars": 731,
"preview": "package config\n\ntype CORS struct {\n\tMode string `mapstructure:\"mode\" json:\"mode\" yaml:\"mode\"`\n\tWhitelist ["
},
{
"path": "server/config/db_list.go",
"chars": 2260,
"preview": "package config\n\nimport (\n\t\"strings\"\n\n\t\"gorm.io/gorm/logger\"\n)\n\ntype DsnProvider interface {\n\tDsn() string\n}\n\n// Embeded "
},
{
"path": "server/config/disk.go",
"chars": 195,
"preview": "package config\n\ntype Disk struct {\n\tMountPoint string `mapstructure:\"mount-point\" json:\"mount-point\" yaml:\"mount-point\"`"
},
{
"path": "server/config/email.go",
"chars": 1065,
"preview": "package config\n\ntype Email struct {\n\tTo string `mapstructure:\"to\" json:\"to\" yaml:\"to\"` "
},
{
"path": "server/config/excel.go",
"chars": 93,
"preview": "package config\n\ntype Excel struct {\n\tDir string `mapstructure:\"dir\" json:\"dir\" yaml:\"dir\"`\n}\n"
},
{
"path": "server/config/gorm_mssql.go",
"chars": 323,
"preview": "package config\n\ntype Mssql struct {\n\tGeneralDB `yaml:\",inline\" mapstructure:\",squash\"`\n}\n\n// Dsn \"sqlserver://gorm:Lorem"
},
{
"path": "server/config/gorm_mysql.go",
"chars": 230,
"preview": "package config\n\ntype Mysql struct {\n\tGeneralDB `yaml:\",inline\" mapstructure:\",squash\"`\n}\n\nfunc (m *Mysql) Dsn() string {"
},
{
"path": "server/config/gorm_oracle.go",
"chars": 350,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/url\"\n)\n\ntype Oracle struct {\n\tGeneralDB `yaml:\",inline\" mapstructure:\",squa"
},
{
"path": "server/config/gorm_pgsql.go",
"chars": 604,
"preview": "package config\n\ntype Pgsql struct {\n\tGeneralDB `yaml:\",inline\" mapstructure:\",squash\"`\n}\n\n// Dsn 基于配置文件获取 dsn\n// Author "
},
{
"path": "server/config/gorm_sqlite.go",
"chars": 200,
"preview": "package config\n\nimport (\n\t\"path/filepath\"\n)\n\ntype Sqlite struct {\n\tGeneralDB `yaml:\",inline\" mapstructure:\",squash\"`\n}\n\n"
},
{
"path": "server/config/jwt.go",
"chars": 428,
"preview": "package config\n\ntype JWT struct {\n\tSigningKey string `mapstructure:\"signing-key\" json:\"signing-key\" yaml:\"signing-key\"`"
},
{
"path": "server/config/mcp.go",
"chars": 738,
"preview": "package config\n\ntype MCP struct {\n\tName string `mapstructure:\"name\" json:\"name\" yaml:\"name\"` "
},
{
"path": "server/config/mongo.go",
"chars": 2246,
"preview": "package config\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Mongo struct {\n\tColl string `json:\"coll\" yaml:\"coll"
},
{
"path": "server/config/oss_aliyun.go",
"chars": 594,
"preview": "package config\n\ntype AliyunOSS struct {\n\tEndpoint string `mapstructure:\"endpoint\" json:\"endpoint\" yaml:\"endpoint\""
},
{
"path": "server/config/oss_aws.go",
"chars": 833,
"preview": "package config\n\ntype AwsS3 struct {\n\tBucket string `mapstructure:\"bucket\" json:\"bucket\" yaml:\"bucket\"`\n\tRegion"
},
{
"path": "server/config/oss_cloudflare.go",
"chars": 567,
"preview": "package config\n\ntype CloudflareR2 struct {\n\tBucket string `mapstructure:\"bucket\" json:\"bucket\" yaml:\"bucket\"`\n\t"
},
{
"path": "server/config/oss_huawei.go",
"chars": 416,
"preview": "package config\n\ntype HuaWeiObs struct {\n\tPath string `mapstructure:\"path\" json:\"path\" yaml:\"path\"`\n\tBucket strin"
},
{
"path": "server/config/oss_local.go",
"chars": 226,
"preview": "package config\n\ntype Local struct {\n\tPath string `mapstructure:\"path\" json:\"path\" yaml:\"path\"` //"
},
{
"path": "server/config/oss_minio.go",
"chars": 669,
"preview": "package config\n\ntype Minio struct {\n\tEndpoint string `mapstructure:\"endpoint\" json:\"endpoint\" yaml:\"endpoint\"`\n\tA"
},
{
"path": "server/config/oss_qiniu.go",
"chars": 818,
"preview": "package config\n\ntype Qiniu struct {\n\tZone string `mapstructure:\"zone\" json:\"zone\" yaml:\"zone\"` "
},
{
"path": "server/config/oss_tencent.go",
"chars": 511,
"preview": "package config\n\ntype TencentCOS struct {\n\tBucket string `mapstructure:\"bucket\" json:\"bucket\" yaml:\"bucket\"`\n\tRegion "
},
{
"path": "server/config/redis.go",
"chars": 676,
"preview": "package config\n\ntype Redis struct {\n\tName string `mapstructure:\"name\" json:\"name\" yaml:\"name\"` "
},
{
"path": "server/config/system.go",
"chars": 1227,
"preview": "package config\n\ntype System struct {\n\tDbType string `mapstructure:\"db-type\" json:\"db-type\" yaml:\"db-type\"` // "
},
{
"path": "server/config/zap.go",
"chars": 2654,
"preview": "package config\n\nimport (\n\t\"go.uber.org/zap/zapcore\"\n\t\"time\"\n)\n\ntype Zap struct {\n\tLevel string `mapstructure:\"le"
},
{
"path": "server/config.docker.yaml",
"chars": 6715,
"preview": "# github.com/flipped-aurora/gin-vue-admin/server Global Configuration\n\n# jwt configuration\njwt:\n signing-key: qmPlus\n"
},
{
"path": "server/config.yaml",
"chars": 6782,
"preview": "# github.com/flipped-aurora/gin-vue-admin/server Global Configuration\n\n# jwt configuration\njwt:\n signing-key: qmPlus\n"
},
{
"path": "server/core/internal/constant.go",
"chars": 221,
"preview": "package internal\n\nconst (\n\tConfigEnv = \"GVA_CONFIG\"\n\tConfigDefaultFile = \"config.yaml\"\n\tConfigTestFile = \"con"
},
{
"path": "server/core/internal/cutter.go",
"chars": 2955,
"preview": "package internal\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Cutter 实现 io.Writer 接口\n// 用于日志切割, strings"
},
{
"path": "server/core/internal/zap_core.go",
"chars": 3723,
"preview": "package internal\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipp"
},
{
"path": "server/core/server.go",
"chars": 1533,
"preview": "package core\n\nimport (\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-v"
},
{
"path": "server/core/server_run.go",
"chars": 1224,
"preview": "package core\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n"
},
{
"path": "server/core/viper.go",
"chars": 1868,
"preview": "package core\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/core/inte"
},
{
"path": "server/core/zap.go",
"chars": 1157,
"preview": "package core\n\nimport (\n \"fmt\"\n \"github.com/flipped-aurora/gin-vue-admin/server/core/internal\"\n \"github.com/flip"
},
{
"path": "server/docs/docs.go",
"chars": 313291,
"preview": "// Code generated by swaggo/swag. DO NOT EDIT.\n\npackage docs\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/"
},
{
"path": "server/docs/swagger.json",
"chars": 312566,
"preview": "{\n \"swagger\": \"2.0\",\n \"info\": {\n \"description\": \"使用gin+vue进行极速开发的全栈开发基础平台\",\n \"title\": \"Gin-Vue-Admin"
},
{
"path": "server/docs/swagger.yaml",
"chars": 130026,
"preview": "definitions:\n common.JSONMap:\n additionalProperties: true\n type: object\n config.AliyunOSS:\n properties:\n "
},
{
"path": "server/global/global.go",
"chars": 1634,
"preview": "package global\n\nimport (\n\t\"fmt\"\n\t\"github.com/mark3labs/mcp-go/server\"\n\t\"sync\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/"
},
{
"path": "server/global/model.go",
"chars": 269,
"preview": "package global\n\nimport (\n\t\"time\"\n\n\t\"gorm.io/gorm\"\n)\n\ntype GVA_MODEL struct {\n\tID uint `gorm:\"primarykey"
},
{
"path": "server/global/version.go",
"chars": 212,
"preview": "package global\n\n// Version 版本信息\n// 目前只有Version正式使用 其余为预留\nconst (\n\t// Version 当前版本号\n\tVersion = \"v2.9.0\"\n\t// AppName 应用名称\n"
},
{
"path": "server/go.mod",
"chars": 9730,
"preview": "module github.com/flipped-aurora/gin-vue-admin/server\n\ngo 1.24.0\n\ntoolchain go1.24.2\n\nrequire (\n\tgithub.com/aliyun/aliyu"
},
{
"path": "server/go.sum",
"chars": 82028,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
},
{
"path": "server/initialize/db_list.go",
"chars": 907,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/initialize/ensure_tables.go",
"chars": 2890,
"preview": "package initialize\n\nimport (\n\t\"context\"\n\tadapter \"github.com/casbin/gorm-adapter/v3\"\n\t\"github.com/flipped-aurora/gin-vue"
},
{
"path": "server/initialize/gorm.go",
"chars": 2109,
"preview": "package initialize\n\nimport (\n\t\"os\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora"
},
{
"path": "server/initialize/gorm_biz.go",
"chars": 206,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n)\n\nfunc bizModel() error {\n\tdb := "
},
{
"path": "server/initialize/gorm_mssql.go",
"chars": 1824,
"preview": "package initialize\n\n/*\n * @Author: 逆光飞翔 191180776@qq.com\n * @Date: 2022-12-08 17:25:49\n * @LastEditors: 逆光飞翔 191180776@q"
},
{
"path": "server/initialize/gorm_mysql.go",
"chars": 1350,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/initialize/gorm_oracle.go",
"chars": 915,
"preview": "package initialize\n\nimport (\n\toracle \"github.com/dzwvip/gorm-oracle\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/co"
},
{
"path": "server/initialize/gorm_pgsql.go",
"chars": 1143,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/initialize/gorm_sqlite.go",
"chars": 905,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/initialize/init.go",
"chars": 242,
"preview": "// 假设这是初始化逻辑的一部分\n\npackage initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/utils\"\n)\n\n// 初始化全局函数\nfun"
},
{
"path": "server/initialize/internal/gorm.go",
"chars": 700,
"preview": "package internal\n\nimport (\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"gorm.io/gorm\"\n\t\"gorm.io/g"
},
{
"path": "server/initialize/internal/gorm_logger_writer.go",
"chars": 916,
"preview": "package internal\n\nimport (\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/g"
},
{
"path": "server/initialize/internal/mongo.go",
"chars": 1131,
"preview": "package internal\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/qiniu/qmgo/options\"\n\t\"go.mongodb.org/mongo-driver/event\"\n\topt "
},
{
"path": "server/initialize/mcp.go",
"chars": 544,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tmcpTool \"github.com/flipped-auror"
},
{
"path": "server/initialize/mongo.go",
"chars": 4551,
"preview": "package initialize\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/fli"
},
{
"path": "server/initialize/other.go",
"chars": 755,
"preview": "package initialize\n\nimport (\n\t\"bufio\"\n\t\"github.com/songzhibin97/gkit/cache/local_cache\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/f"
},
{
"path": "server/initialize/plugin.go",
"chars": 380,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/gin-gonic/gin\"\n)\n\nfun"
},
{
"path": "server/initialize/plugin_biz_v1.go",
"chars": 1018,
"preview": "package initialize\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-auror"
},
{
"path": "server/initialize/plugin_biz_v2.go",
"chars": 408,
"preview": "package initialize\n\nimport (\n\t_ \"github.com/flipped-aurora/gin-vue-admin/server/plugin\"\n\t\"github.com/flipped-aurora/gin-"
},
{
"path": "server/initialize/redis.go",
"chars": 1415,
"preview": "package initialize\n\nimport (\n\t\"context\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-a"
},
{
"path": "server/initialize/register_init.go",
"chars": 255,
"preview": "package initialize\n\nimport (\n\t_ \"github.com/flipped-aurora/gin-vue-admin/server/source/example\"\n\t_ \"github.com/flipped-a"
},
{
"path": "server/initialize/reload.go",
"chars": 734,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"go.uber.org/zap\"\n)\n\n// Reload 优雅"
},
{
"path": "server/initialize/router.go",
"chars": 4875,
"preview": "package initialize\n\nimport (\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/docs\"\n\t\"github.com/flip"
},
{
"path": "server/initialize/router_biz.go",
"chars": 383,
"preview": "package initialize\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/router\"\n\t\"github.com/gin-gonic/gin\"\n)\n\n// "
},
{
"path": "server/initialize/timer.go",
"chars": 814,
"preview": "package initialize\n\nimport (\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/task\"\n\n\t\"github.com/robfig/cron/v3\""
},
{
"path": "server/initialize/validator.go",
"chars": 424,
"preview": "package initialize\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/utils\"\n\nfunc init() {\n\t_ = utils.RegisterRule"
},
{
"path": "server/main.go",
"chars": 1400,
"preview": "package main\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/core\"\n\t\"github.com/flipped-aurora/gin-vue-admin/"
},
{
"path": "server/mcp/api_creator.go",
"chars": 4795,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server"
},
{
"path": "server/mcp/api_lister.go",
"chars": 4057,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t"
},
{
"path": "server/mcp/client/client.go",
"chars": 832,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"errors\"\n\tmcpClient \"github.com/mark3labs/mcp-go/client\"\n\t\"github.com/mark3labs/mcp"
},
{
"path": "server/mcp/client/client_test.go",
"chars": 3286,
"preview": "package client\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\t\"testing\"\n)\n\n// 测试 MCP 客户端连接\nfunc TestMcp"
},
{
"path": "server/mcp/dictionary_generator.go",
"chars": 6027,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server"
},
{
"path": "server/mcp/dictionary_query.go",
"chars": 6079,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t"
},
{
"path": "server/mcp/enter.go",
"chars": 676,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"github.com/mark3labs/mcp-go/mcp\"\n\t\"github.com/mark3labs/mcp-go/server\"\n)\n\n// McpT"
},
{
"path": "server/mcp/gva_analyze.go",
"chars": 14440,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\tmodel \"github.com/flipped-aurora/gin-vue-admin/s"
},
{
"path": "server/mcp/gva_execute.go",
"chars": 32224,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\tmodel \"github.com/flipped-aurora/gin-vue-admin/s"
},
{
"path": "server/mcp/gva_review.go",
"chars": 4626,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/mark3labs/mcp-go/mcp\"\n)\n"
},
{
"path": "server/mcp/menu_creator.go",
"chars": 6985,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server"
},
{
"path": "server/mcp/menu_lister.go",
"chars": 2542,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t"
},
{
"path": "server/mcp/requirement_analyzer.go",
"chars": 3918,
"preview": "package mcpTool\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/mark3labs/mcp-go/mcp\"\n)\n\nfunc init("
},
{
"path": "server/middleware/casbin_rbac.go",
"chars": 795,
"preview": "package middleware\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/middleware/cors.go",
"chars": 2203,
"preview": "package middleware\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"github.com/flipped-aurora/gin-vu"
},
{
"path": "server/middleware/email.go",
"chars": 1666,
"preview": "package middleware\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/plugin/"
},
{
"path": "server/middleware/error.go",
"chars": 2357,
"preview": "package middleware\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\""
},
{
"path": "server/middleware/jwt.go",
"chars": 2481,
"preview": "package middleware\n\nimport (\n\t\"errors\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"gi"
},
{
"path": "server/middleware/limit_ip.go",
"chars": 2356,
"preview": "package middleware\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"go.uber.org/zap\"\n\n\t\"github.com/flipped-aurora/g"
},
{
"path": "server/middleware/loadtls.go",
"chars": 446,
"preview": "package middleware\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/gin-gonic/gin\"\n\t\"github.com/unrolled/secure\"\n)\n\n// 用https把这个中间件在router"
},
{
"path": "server/middleware/logger.go",
"chars": 2009,
"preview": "package middleware\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\n/"
},
{
"path": "server/middleware/operation.go",
"chars": 3402,
"preview": "package middleware\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time"
},
{
"path": "server/middleware/timeout.go",
"chars": 1068,
"preview": "package middleware\n\nimport (\n\t\"context\"\n\t\"github.com/gin-gonic/gin\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// TimeoutMiddleware 创建超时中间件\n"
},
{
"path": "server/model/common/basetypes.go",
"chars": 743,
"preview": "package common\n\nimport (\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\ntype JSONMap map[string]interface{}\n\nfunc "
},
{
"path": "server/model/common/clearDB.go",
"chars": 103,
"preview": "package common\n\ntype ClearDB struct {\n\tTableName string\n\tCompareField string\n\tInterval string\n}\n"
},
{
"path": "server/model/common/request/common.go",
"chars": 991,
"preview": "package request\n\nimport (\n\t\"gorm.io/gorm\"\n)\n\n// PageInfo Paging common input parameter structure\ntype PageInfo struct {\n"
},
{
"path": "server/model/common/response/common.go",
"chars": 194,
"preview": "package response\n\ntype PageResult struct {\n\tList interface{} `json:\"list\"`\n\tTotal int64 `json:\"total\"`\n\tPag"
},
{
"path": "server/model/common/response/response.go",
"chars": 1175,
"preview": "package response\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/gin-gonic/gin\"\n)\n\ntype Response struct {\n\tCode int `json:\"c"
},
{
"path": "server/model/example/exa_attachment_category.go",
"chars": 527,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n)\n\ntype ExaAttachmentCategory struct "
},
{
"path": "server/model/example/exa_breakpoint_continue.go",
"chars": 422,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n)\n\n// file struct, 文件结构体\ntype ExaFile"
},
{
"path": "server/model/example/exa_customer.go",
"chars": 792,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-a"
},
{
"path": "server/model/example/exa_file_upload_download.go",
"chars": 798,
"preview": "package example\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n)\n\ntype ExaFileUploadAndDownload stru"
},
{
"path": "server/model/example/request/exa_file_upload_and_downloads.go",
"chars": 207,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n)\n\ntype ExaAttachmentCa"
},
{
"path": "server/model/example/response/exa_breakpoint_continue.go",
"chars": 223,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/example\"\n\ntype FilePathResponse struct {\n"
},
{
"path": "server/model/example/response/exa_customer.go",
"chars": 173,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/example\"\n\ntype ExaCustomerResponse struct"
},
{
"path": "server/model/example/response/exa_file_upload_download.go",
"chars": 174,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/example\"\n\ntype ExaFileResponse struct {\n\t"
},
{
"path": "server/model/system/request/jwt.go",
"chars": 325,
"preview": "package request\n\nimport (\n\tjwt \"github.com/golang-jwt/jwt/v5\"\n\t\"github.com/google/uuid\"\n)\n\n// CustomClaims structure\ntyp"
},
{
"path": "server/model/system/request/sys_api.go",
"chars": 655,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_api_token.go",
"chars": 282,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_authority_btn.go",
"chars": 167,
"preview": "package request\n\ntype SysAuthorityBtnReq struct {\n\tMenuID uint `json:\"menuID\"`\n\tAuthorityId uint `json:\"authori"
},
{
"path": "server/model/system/request/sys_auto_code.go",
"chars": 10799,
"preview": "package request\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tmodel \"githu"
},
{
"path": "server/model/system/request/sys_auto_code_mcp.go",
"chars": 740,
"preview": "package request\n\ntype AutoMcpTool struct {\n\tName string `json:\"name\" form:\"name\" binding:\"required\"`\n\tDescription"
},
{
"path": "server/model/system/request/sys_auto_code_package.go",
"chars": 860,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\tmodel \"github.com/flipped-aurora/gin"
},
{
"path": "server/model/system/request/sys_auto_history.go",
"chars": 1807,
"preview": "package request\n\nimport (\n\tcommon \"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\tmodel \"github.c"
},
{
"path": "server/model/system/request/sys_casbin.go",
"chars": 858,
"preview": "package request\n\n// CasbinInfo Casbin info structure\ntype CasbinInfo struct {\n\tPath string `json:\"path\"` // 路径\n\tMeth"
},
{
"path": "server/model/system/request/sys_dictionary.go",
"chars": 237,
"preview": "package request\n\ntype SysDictionarySearch struct {\n\tName string `json:\"name\" form:\"name\" gorm:\"column:name;comment:字典名(中"
},
{
"path": "server/model/system/request/sys_dictionary_detail.go",
"chars": 2490,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_error.go",
"chars": 333,
"preview": "\npackage request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"time\"\n)\n\ntype SysErr"
},
{
"path": "server/model/system/request/sys_export_template.go",
"chars": 397,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_init.go",
"chars": 3413,
"preview": "package request\n\nimport (\n\t\"fmt\"\n\t\"github.com/flipped-aurora/gin-vue-admin/server/config\"\n\t\"os\"\n)\n\ntype InitDB struct {\n"
},
{
"path": "server/model/system/request/sys_login_log.go",
"chars": 235,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_menu.go",
"chars": 882,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/global\"\n\t\"github.com/flipped-aurora/gin-vue-a"
},
{
"path": "server/model/system/request/sys_operation_record.go",
"chars": 249,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/request/sys_params.go",
"chars": 406,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"time\"\n)\n\ntype SysPara"
},
{
"path": "server/model/system/request/sys_skills.go",
"chars": 1943,
"preview": "package request\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\ntype SkillToolRequest struct {\n\tT"
},
{
"path": "server/model/system/request/sys_user.go",
"chars": 3350,
"preview": "package request\n\nimport (\n\tcommon \"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/fli"
},
{
"path": "server/model/system/request/sys_version.go",
"chars": 1711,
"preview": "package request\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/common/request\"\n\t\"github.com/flipped-au"
},
{
"path": "server/model/system/response/sys_api.go",
"chars": 350,
"preview": "package response\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n)\n\ntype SysAPIResponse struct "
},
{
"path": "server/model/system/response/sys_authority.go",
"chars": 341,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\ntype SysAuthorityResponse struct"
},
{
"path": "server/model/system/response/sys_authority_btn.go",
"chars": 88,
"preview": "package response\n\ntype SysAuthorityBtnRes struct {\n\tSelected []uint `json:\"selected\"`\n}\n"
},
{
"path": "server/model/system/response/sys_auto_code.go",
"chars": 946,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\ntype Db struct {\n\tDatabase strin"
},
{
"path": "server/model/system/response/sys_captcha.go",
"chars": 221,
"preview": "package response\n\ntype SysCaptchaResponse struct {\n\tCaptchaId string `json:\"captchaId\"`\n\tPicPath string `json:"
},
{
"path": "server/model/system/response/sys_casbin.go",
"chars": 179,
"preview": "package response\n\nimport (\n\t\"github.com/flipped-aurora/gin-vue-admin/server/model/system/request\"\n)\n\ntype PolicyPathResp"
},
{
"path": "server/model/system/response/sys_menu.go",
"chars": 317,
"preview": "package response\n\nimport \"github.com/flipped-aurora/gin-vue-admin/server/model/system\"\n\ntype SysMenusResponse struct {\n\t"
}
]
// ... and 446 more files (download for full content)
About this extraction
This page contains the full source code of the flipped-aurora/gin-vue-admin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 646 files (3.0 MB), approximately 810.4k tokens, and a symbol index with 1568 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.