HotGo-V2 Documentation

repository·v2.0·Indexed 24 days ago

https://github.com/bufanyun/hotgo

An enterprise-grade full-stack framework built with GoFrame2, Vue3, NaiveUI, and uniapp. It features a plugin-based micro-kernel architecture for high-productivity secondary development, supporting automated CURD code generation, multi-tenancy (SaaS), and integrated identity and access management via JWT and Casbin. The framework includes built-in modules for financial payments, message queues (Kafka, Redis, RocketMQ), WebSocket/TCP servers, and comprehensive system administration tools.

Tokens
102.8K
Snippets
212
Records
560
Agent score
84%

What's inside HotGo-V2

  1. Overview of HotGo system utility libraries

    v2.0
    HotGo provides a collection of common system utility libraries located under the /server/utility directory. These utilities cover various common tasks such as string manipulation, data conversion, encryption, and file handling to streamline backend development.
  2. Overview of HotGo-V2

    v2.0

    HotGo-V2 is an enterprise-grade full-stack framework designed for rapid secondary development. It is built on a modern tech stack including GoFrame2, Vue3, NaiveUI, and uniapp.

    Key architectural features include:

    • Multi-entry points: Supports different business logic through dedicated entries for Admin (backend), Home (frontend), Api (general interfaces), and WebSocket (real-time communication).
    • Micro-kernel Architecture: Features an extreme plugin system that allows for functional isolation, high customizability, and progressive development. Plugins can be created from templates, installed, updated, or uninstalled easily, making them highly portable between projects.
    • High Productivity: Provides automated code generation for CURD and tree-table structures based on database configurations, reducing manual coding requirements.
    • Security: Implements user state authentication via JWT and permission management via Casbin.
  3. HotGo-V2 Documentation Roadmap

    v2.0

    The HotGo-V2 documentation is organized into several key areas to guide developers through setup, system development, plugin creation, code generation, and frontend development.

    1. Getting Started (Installation & Setup)

    Covers system introduction, environment setup, installation, production deployment, and troubleshooting.

    2. System Development

    Covers core backend capabilities including:

    • Directory structure and development standards
    • Console, Middleware/Interceptors, and WebHooks
    • Permission control, Payment gateways, and Cron jobs
    • Message queues, Function extension libraries, and Utility methods
    • WebSocket and TCP servers
    • SaaS multi-tenancy and Internationalization (i18n)
    • Unit testing

    3. Plugin/Addon Module Development

    Covers module introduction, directory structures, development workflows, and helper utilities for building extensions.

    4. Code Generation

    Provides guides for automating development using:

    • Database integration
    • Generation configuration
    • CURD (Create, Update, Read, Delete) generation for single tables, joined tables, and tree-structured data
    • Business template and template development
    • Common problem/FAQ generation

    5. Frontend Development

    Covers frontend-specific tasks including:

    • Form components
    • WebSocket client implementation
    • Independent deployment
  4. Use database patches to support database-specific features

    v2.0

    HotGo uses database patches to bridge differences between various database engines, enabling features that rely on specific database capabilities. Currently, this includes support for adding comments to database table fields and table names, which is particularly useful for SQLite.

    Note for SQLite users: Due to the specific nature of SQLite, there are requirements for the SQL statements used when creating tables. You must follow the specific format demonstrated in the provided example file.

  5. WebSocket authentication and security

    v2.0

    By default, WebSocket connections are protected by an authentication middleware (WebSocketAuth). Users must be successfully logged in before they can establish a connection. This middleware extracts user information and injects it into the request context.

    If you require unauthenticated WebSocket access, you must modify the authentication middleware to bypass the login check for specific routes, though this is generally discouraged for security reasons.

  6. How to use multiple databases with code generation

    v2.0

    To support code generation across multiple databases, you must configure both the gfcli and the hggen sections.

    1. Update server/hack/config.yaml: Add multiple entries under gfcli.gen.dao, each with a unique group name.
    2. Update server/manifest/config/config.yaml:
      • In the database section, define each database connection with its own configuration name (e.g., default, default2).
      • In the hggen section, add the database configuration names to the selectDbs list.
    3. Use in UI: When using the Code Generation tool in the Admin UI, the new database option will appear in the selection dropdown.
  7. Understand Data Permission Scopes

    v2.0

    Data permissions restrict the data visible to a user based on specific scopes. This is useful for multi-departmental organizations or multi-level agent/distributor systems.

    Supported Scopes:

    • All Permissions (全部权限): No filtering; user sees all data.
    • Current Department (当前部门): User sees only data within their own department.
    • Current and Sub-departments (当前以及下部门): User sees data from their department and all nested sub-departments.
    • Custom Department (自定义部门): User sees data from specific departments selected by the admin.
    • Only Self (仅自己): User sees only their own data.
    • Self and Direct Subordinates (自己和直属下级): User sees their own data and data from users exactly one level below them.
    • Self and All Subordinates (自己和全部下级): User sees their own data and all data from all users in their hierarchy below them.

    Key Concepts:

    • Departments vs. Subordinates: Departments are typically used in organizational structures (managed via Organization Management -> Backend User -> Bind Department). Subordinates are common in agent systems (the user who added another user is considered their superior/parent).
    • Identifying Ownership: To support 'Self' and 'Subordinate' scopes, your database tables must include either a created_by or member_id field.
  8. Understand the Web Frontend Directory Structure

    v2.0

    The web frontend is a Vite-based project. The main structure is as follows:

    • src/api: Interface/API definition files.
    • src/components: Common reusable components.
    • src/hooks: Reusable logic via hooks (categorized into component, core, event, setting, and web).
    • src/layouts: Layout files (e.g., default, iframe, page).
    • src/logics: Business logic files.
    • src/store: Data warehouse/state management.
    • src/views: Page components.
    • src/settings: Project configuration files (e.g., componentSetting.ts, designSetting.ts, projectSetting.ts).
    • src/locales: Multi-language support files.
    • src/directives: Custom Vue directives.
    • src/enums: Enumerations and constants.
    • src/assets: Static assets (icons, images, svg).
    • build: Build-related scripts, configurations, and Vite settings.
    • public: Public static resource directory.
    • types: TypeScript type definition files.
  9. Automate Tenant Relationship Maintenance

    v2.0

    You can automate tenant permission filtering and relationship maintenance by including specific ID fields in your database tables and using HotGo's handler and hook mechanisms.

    Required Fields

    To use the automatic maintenance features, include the following fields in your table design:

    Field NameTypeDescription
    tenant_idbigint(20)Tenant ID
    merchant_idbigint(20)Merchant ID
    user_idbigint(20)User ID

    Implementation Steps

    1. Encapsulate the Query Model with Filtering

    When defining your Model, use handler.Option with FilterTenant: true to automatically filter data based on the current tenant's permissions.

    2. Use Hooks for Automatic Updates

    When performing Insert or Update operations, attach the hook.SaveTenant hook. This ensures that tenant_id, merchant_id, and user_id are automatically maintained/updated based on the context.

    // Example: Encapsulating a Model with tenant filtering
    func (s *sSysTenantOrder) Model(ctx context.Context, option ...*handler.Option) *gdb.Model {
    	if len(option) == 0 {
    		// 过滤多租户数据权限
    		option = append(option, &handler.Option{
    			FilterTenant: true,
    			//FilterAuth:   true, // If you also need to maintain dept permissions like created_by
    		})
    	}
    	return handler.Model(dao.AddonHgexampleTenantOrder.Ctx(ctx), option...)
    }
    
    // Example: Using hook.SaveTenant for automatic relationship maintenance
    func (s *sSysTenantOrder) Edit(ctx context.Context, in *sysin.TenantOrderEditInp) (err error) {
    	return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
    
    		// Update
    		if in.Id > 0 {
    			if _, err = s.Model(ctx).
    				Fields(sysin.TenantOrderUpdateFields{}).
    				WherePri(in.Id).
    				Data(in).
    				Hook(hook.SaveTenant). // Automatically maintains tenant relationships
    				Update(); err != nil {
    				}
    				return
    		}
    
    		// Insert
    		if _, err = dao.AddonHgexampleTenantOrder.Ctx(ctx).
    			Fields(sysin.TenantOrderInsertFields{}).
    			Hook(hook.SaveTenant). // Automatically maintains tenant relationships
    			Data(in).
    			Insert(); err != nil {
    				return
    			}
    		return
    	})
    }
  10. Understand the HotGo-V2 Server Directory Structure

    v2.0

    The HotGo-V2 server architecture is based on a modified GoFrame (gf) structure. It is organized into several key top-level directories:

    • addons: The location for all plugin modules. Each plugin is self-contained and supports hot-swapping/plugging.
    • api: Defines the external interface structures (input/output) for different access layers (admin, general API, home, and websocket).
    • internal: Contains the core business logic. This directory uses Go's internal visibility rules to prevent external packages from accessing private implementation details.
    • manifest: Contains files for compilation, deployment, and runtime configuration (e.g., config, docker, deploy).
    • resource: Static resource files that can be injected into the release via resource packaging or image compilation.
    • storage: Local data storage directory for file caches, disk queues, SQL files, and SSL certificates.
    • utility: Common utility methods.
    • main.go: The application entry point.
    • Makefile: Contains shortcut commands for development and building/releasing the project.
  11. Call main module services from a plugin without import cycles

    v2.0

    When a plugin needs to call a service provided by the main module, do not use the main module's input structures directly in your plugin's logic. This prevents import cycle not allowed errors when using gf gen service.

    Recommended Pattern:

    1. Create a new input structure in your plugin's input layer that embeds (inherits) the main module's input structure.
    2. In your plugin's business logic, map the plugin's input to the main module's input and call the main module's service.

    Example: To update plugin configuration via the main module's service:

    1. Plugin Input (\server\addons\hgexample\model\input\sysin\config.go):

    package sysin
    
    import (
    	"hotgo/internal/model/input/sysin"
    )
    
    // UpdateConfigInp embeds the main module's input
    type UpdateConfigInp struct {
    	sysin.UpdateAddonsConfigInp
    }

    2. Plugin Logic (\server\addons\hgexample\logic\sys\config.go):

    func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error {
    	// Set required fields from the plugin's global context
    	in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
    	// Call the main module service using the embedded input
    	return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp)
    }
    // Plugin Input
    type UpdateConfigInp struct {
    	sysin.UpdateAddonsConfigInp
    }
    
    // Plugin Logic implementation
    func (s *sSysConfig) UpdateConfigByGroup(ctx context.Context, in sysin.UpdateConfigInp) error {
    	in.UpdateAddonsConfigInp.AddonName = global.GetSkeleton().Name
    	return isc.SysAddonsConfig().UpdateConfigByGroup(ctx, in.UpdateAddonsConfigInp)
    }