GetAllTables()
+ {
+ return _memoryCache.GetOrCreate(CACHE_KEY, entry =>
+ {
+ entry.SlidingExpiration = CACHE_DURATION; // 滑动过期
+ return _dataSourceManager.GetAllTables();
+ });
+ }
+}
+```
+
+**缓存特性:**
+- ⏱️ **过期策略**:滑动过期,20 分钟无访问自动清除
+- 🔄 **手动刷新**:调用 `RefreshCache()` 方法
+- 🗑️ **手动清除**:调用 `ClearCache()` 方法
+- 📊 **缓存键**:`CodeGenerator:AllTables`
+
+---
+
+## 四、完整流程详解
+
+### 4.1 流程 1:获取数据库列表
+
+**前端请求:**
+```http
+GET /api/CodeGeneration/databases
+```
+
+**处理流程:**
+```
+Controller.GetDatabasesAsync()
+ ↓
+CodeGenerationService.GetAllDataSources()
+ ↓
+DataSourceManager.GetAllProviders()
+ ↓
+自动收集所有实现 IDataSourceProvider 的类
+```
+
+**返回数据:**
+```json
+[
+ {
+ "key": "Admin",
+ "displayName": "后台管理系统"
+ },
+ {
+ "key": "MiaoYuChat",
+ "displayName": "喵语AI聊天"
+ },
+ {
+ "key": "LiveForum",
+ "displayName": "直播论坛系统"
+ }
+]
+```
+
+---
+
+### 4.2 流程 2:获取表列表(带筛选)
+
+**前端请求:**
+```http
+POST /api/CodeGeneration/50/1
+Content-Type: application/json
+
+{
+ "tableName": "User",
+ "dataBase": "MiaoYuChat"
+}
+```
+
+**处理流程:**
+
+```
+1️⃣ 获取缓存或查询数据库
+ DatabaseTableService.GetAllTablesByCache()
+ ↓
+ TableSchemaCache.GetAllTables()
+ ↓
+ [缓存命中] → 直接返回
+ [缓存未命中] → 查询数据库
+ ↓
+ DataSourceManager.GetAllTables()
+ ↓
+ 遍历所有 Provider:
+ - AdminDataSourceProvider.GetTables()
+ → FreeSql.DbFirst.GetTablesByDatabase()
+ - MiaoYuChatDataSourceProvider.GetTables()
+ → FreeSql.DbFirst.GetTablesByDatabase()
+ ↓
+ 标记每个表的 DataBase 字段
+
+2️⃣ 合并配置文件
+ DatabaseTableService.MergeTableWithConfig()
+ ↓
+ 对每个表:
+ 读取: CodeGenConfig/{DataBase}/{TableName}.json
+ 合并: DisplayName, EntityName, 列配置等
+
+3️⃣ 应用筛选条件
+ - WHERE DataBase = "MiaoYuChat" ✅
+ - AND TableName LIKE "%User%" ✅
+
+4️⃣ 分页处理
+ - Skip((page-1) * size)
+ - Take(size)
+```
+
+**返回数据:**
+```json
+{
+ "total": 5,
+ "page": 1,
+ "size": 50,
+ "pageCount": 1,
+ "dataSource": [
+ {
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat",
+ "entityName": "T_User",
+ "displayName": "用户表",
+ "remark": "系统用户信息"
+ },
+ {
+ "tableName": "T_User_Currency",
+ "dataBase": "MiaoYuChat",
+ "entityName": "T_User_Currency",
+ "displayName": "用户货币",
+ "remark": "用户虚拟货币"
+ }
+ ]
+}
+```
+
+---
+
+### 4.3 流程 3:生成代码(核心)
+
+**前端请求:**
+```http
+POST /api/CodeGeneration/GetCodeAsync
+Content-Type: application/json
+
+{
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat",
+ "type": "MiaoYu.Models"
+}
+```
+
+**处理流程:**
+
+```
+1️⃣ 路由到生成方法
+ GetCodeByTypeAndTableNameAsync(genFormDto)
+ ↓
+ 根据 Type 分支:
+ - "MiaoYu.Models" → GenModelAsync()
+ - "MiaoYu.Services.Admin" → GenServiceAsync()
+ - "MiaoYu.Controllers.Admin" → GenControllerAsync()
+ - "Client.Index" → GenIndexAsync()
+ - "Client.Info" → GenInfoAsync()
+ - "Client.Service" → GenServiceJsAsync()
+
+2️⃣ 构建生成上下文(以 GenModelAsync 为例)
+ GetGenContextDto(genFormDto)
+ ↓
+ A. 获取表信息
+ GetGenContextDtoByTableName("T_User", "MiaoYuChat")
+ ↓
+ 从缓存/数据库查询表结构
+
+ B. 获取数据源配置
+ DataSourceManager.GetProvider("MiaoYuChat")
+ ↓
+ 找到 MiaoYuChatDataSourceProvider
+ 读取其 Config
+
+ C. 解析路径模板
+ PathResolver.ResolvePath(config.ModelPathTemplate, config, "T_User")
+ ↓
+ 替换占位符:
+ {RootPath} → "D:\CodeManage\HuanMengAdmin\HuanMengAdmin"
+ {Namespace} → "MiaoYu.Repository.ChatAI.Admin"
+ {EntityName} → "T_User"
+ {TableName} → "T_User"
+
+ D. 构建完整上下文
+ GenDbTableDto {
+ TableName: "T_User",
+ DataBase: "MiaoYuChat",
+ EntityName: "T_User",
+ DisplayName: "用户表",
+ ModelPath: "D:\...\Entities\Apps",
+ Namespace: "MiaoYu.Repository.ChatAI.Admin",
+ TableInfos: [
+ {
+ ColumnName: "Id",
+ CsType: "Guid",
+ IsPrimary: true,
+ Describe: "主键ID",
+ ...
+ },
+ ...
+ ]
+ }
+
+3️⃣ Razor 模板渲染
+ _razorViewRender.RenderAsync(templatePath + "tempModel.cshtml", context)
+ ↓
+ 模板文件: /wwwroot/code_generation/templatev4/tempModel.cshtml
+ ↓
+ Razor 处理:
+ @model GenDbTableDto
+
+ namespace @Model.Namespace.Entities
+ {
+ ///
+ /// @Model.DisplayName
+ ///
+ public class @Model.EntityName
+ {
+ @foreach(var col in Model.TableInfos)
+ {
+ ///
+ /// @col.Describe
+ ///
+ public @col.CsType @col.ColumnName { get; set; }
+ }
+ }
+ }
+
+4️⃣ 清理和返回
+ ClearSymbol(code) // 移除 标签等
+ ↓
+ 返回生成的代码字符串
+```
+
+**返回数据(示例):**
+```csharp
+namespace MiaoYu.Repository.ChatAI.Admin.Entities
+{
+ ///
+ /// 用户表
+ ///
+ public class T_User
+ {
+ ///
+ /// 主键ID
+ ///
+ [Key]
+ public Guid Id { get; set; }
+
+ ///
+ /// 用户名
+ ///
+ public string UserName { get; set; }
+
+ ///
+ /// 手机号
+ ///
+ public string? Phone { get; set; }
+
+ // ... 其他字段
+ }
+}
+```
+
+---
+
+### 4.4 流程 4:自动导入项目
+
+**前端请求:**
+```http
+POST /api/CodeGeneration/AutoImprotProjectAsync
+Content-Type: application/json
+
+{
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat"
+}
+```
+
+**处理流程:**
+
+```
+1️⃣ 遍历所有文件类型
+ FileTypeEnum[] = {
+ Model, // .cs 实体类
+ Service, // .cs 服务类
+ Controller, // .cs 控制器
+ ClientIndex, // .vue 列表页面
+ ClientInfo, // .vue 详情页面
+ ClientService // .ts 前端服务
+ }
+
+2️⃣ 对每个文件类型执行:
+
+ A. 计算目标路径
+ GetFileAbsolutelyPath(tableName, fileType, dataBase)
+ ↓
+ 根据 Provider 配置解析:
+ Model: "D:\...\Entities\Apps\T_User.cs"
+ Service: "D:\...\ApplicationServices\Apps\MiaoYuChat\T_UserService.cs"
+ Controller: "D:\...\Controllers\Apps\MiaoYuChat\T_UserController.cs"
+ ClientIndex: "D:\...\admin-client\src\views\apps\T_Users\Index.vue"
+
+ B. 检查文件是否存在
+ if (File.Exists(filePath) && !table.IsCover)
+ → 生成带时间戳的文件名:T_User20241107123045.cs
+
+ C. 生成代码
+ SaveToFileAsync(tableName, fileType, filePath)
+ ↓
+ 调用对应生成方法获取代码
+
+ D. 写入文件
+ Directory.CreateDirectory(dirPath) // 确保目录存在
+ File.WriteAllTextAsync(filePath, code, UTF8)
+
+3️⃣ 保存配置文件
+ SaveTableMetaConfigAsync(tableDto)
+ ↓
+ 创建: CodeGenConfig/MiaoYuChat/T_User.json
+ {
+ "displayName": "用户表",
+ "entityName": "T_User",
+ "modelPath": "D:\\...\\Entities\\Apps",
+ "isCover": false,
+ "columns": {
+ "Id": {
+ "displayName": "用户ID",
+ "isTableColumnShow": true
+ }
+ }
+ }
+
+4️⃣ 完成
+ 返回 true,所有文件已生成并导入
+```
+
+**生成的文件结构:**
+```
+MiaoYu.Repository.ChatAI.Admin/
+└── Entities/
+ └── Apps/
+ └── T_User.cs ✅
+
+MiaoYu.Api.Admin/
+├── ApplicationServices/
+│ └── Apps/
+│ └── MiaoYuChat/
+│ └── T_UserService.cs ✅
+└── Controllers/
+ └── Apps/
+ └── MiaoYuChat/
+ └── T_UserController.cs ✅
+
+admin-client/
+└── src/
+ ├── views/
+ │ └── apps/
+ │ └── T_Users/
+ │ ├── Index.vue ✅
+ │ └── Info.vue ✅
+ └── services/
+ └── apps/
+ └── T_Users/
+ └── T_UserService.ts ✅
+
+CodeGenConfig/
+└── MiaoYuChat/
+ └── T_User.json ✅
+```
+
+---
+
+## 五、配置说明
+
+### 5.1 数据源配置
+
+#### 5.1.1 配置模型
+
+```csharp
+public class DataSourceConfig
+{
+ ///
+ /// 数据库标识(如:Admin, MiaoYuChat)
+ ///
+ public string DatabaseKey { get; set; }
+
+ ///
+ /// 显示名称
+ ///
+ public string DisplayName { get; set; }
+
+ ///
+ /// 实体项目命名空间
+ ///
+ public string EntityNamespace { get; set; }
+
+ ///
+ /// 实体类路径模板
+ /// 支持占位符:{RootPath}, {AppPath}, {Namespace},
+ /// {EntityName}, {EntityNamePlural}, {TableName}
+ ///
+ public string ModelPathTemplate { get; set; }
+
+ ///
+ /// 服务层路径模板
+ ///
+ public string ServicePathTemplate { get; set; }
+
+ ///
+ /// 控制器路径模板
+ ///
+ public string ControllerPathTemplate { get; set; }
+
+ ///
+ /// 代码生成模板目录
+ ///
+ public string TemplatePath { get; set; }
+
+ ///
+ /// 实体类命名规则(保持原名 or 驼峰转换)
+ ///
+ public EntityNamingStrategy NamingStrategy { get; set; }
+
+ ///
+ /// 是否使用复数形式的路径
+ ///
+ public bool UsesPluralPath { get; set; }
+
+ ///
+ /// 排序权重(数字越小越靠前)
+ ///
+ public int Order { get; set; }
+}
+```
+
+#### 5.1.2 路径占位符
+
+| 占位符 | 说明 | 示例 |
+|--------|------|------|
+| `{RootPath}` | 解决方案根目录 | `D:\Projects\HuanMengAdmin` |
+| `{AppPath}` | 当前应用根目录 | `D:\Projects\HuanMengAdmin\admin-server\MiaoYu.Api.Admin` |
+| `{Namespace}` | 实体命名空间 | `MiaoYu.Repository.ChatAI.Admin` |
+| `{EntityName}` | 实体名称(单数) | `User` |
+| `{EntityNamePlural}` | 实体名称(复数) | `Users` |
+| `{TableName}` | 表名(原始) | `T_User` |
+
+#### 5.1.3 命名策略
+
+```csharp
+public enum EntityNamingStrategy
+{
+ ///
+ /// 保持数据库表名原样
+ ///
+ KeepOriginal,
+
+ ///
+ /// 转换为驼峰命名(去除下划线前缀)
+ /// sys_user → SysUser
+ /// t_image_config → TImageConfig
+ ///
+ ToPascalCase
+}
+```
+
+**转换示例:**
+```
+KeepOriginal 模式:
+ T_User → T_User
+ sys_user → sys_user
+
+ToPascalCase 模式:
+ T_User → TUser
+ sys_user → SysUser
+ t_image_config → TImageConfig
+```
+
+### 5.2 表元信息配置
+
+#### 5.2.1 配置文件位置
+
+```
+CodeGenConfig/
+├── Admin/
+│ ├── SysUser.json
+│ ├── SysRole.json
+│ └── ...
+├── MiaoYuChat/
+│ ├── T_User.json
+│ ├── T_Character.json
+│ └── ...
+└── LiveForum/
+ └── ...
+```
+
+#### 5.2.2 配置文件结构
+
+```json
+{
+ "displayName": "用户表",
+ "entityName": "T_User",
+ "remark": "系统用户信息表",
+ "modelPath": "D:\\Projects\\HuanMengAdmin\\MiaoYu.Repository.ChatAI.Admin\\Entities\\Apps",
+ "servicePath": "D:\\Projects\\HuanMengAdmin\\admin-server\\MiaoYu.Api.Admin\\ApplicationServices\\Apps\\MiaoYuChat",
+ "controllerPath": "D:\\Projects\\HuanMengAdmin\\admin-server\\MiaoYu.Api.Admin\\Controllers\\Apps\\MiaoYuChat",
+ "clientIndexPath": "D:\\Projects\\HuanMengAdmin\\admin-client\\src\\views\\apps\\T_Users",
+ "clientInfoPath": "D:\\Projects\\HuanMengAdmin\\admin-client\\src\\views\\apps\\T_Users",
+ "clientServicePath": "D:\\Projects\\HuanMengAdmin\\admin-client\\src\\services\\apps\\T_Users",
+ "isCover": false,
+ "columns": {
+ "Id": {
+ "displayName": "用户ID",
+ "describe": "主键ID",
+ "csField": "Id",
+ "isTableSelect": false,
+ "isImageId": false,
+ "isTableColumnShow": true
+ },
+ "UserName": {
+ "displayName": "用户名",
+ "describe": "登录用户名",
+ "csField": "UserName",
+ "isTableSelect": true,
+ "isImageId": false,
+ "isTableColumnShow": true
+ },
+ "Avatar": {
+ "displayName": "头像",
+ "describe": "用户头像URL",
+ "csField": "Avatar",
+ "isTableSelect": false,
+ "isImageId": true,
+ "isTableColumnShow": true
+ }
+ }
+}
+```
+
+#### 5.2.3 配置字段说明
+
+**表级配置:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| displayName | string | 表的显示名称 |
+| entityName | string | 实体类名称 |
+| remark | string | 表备注说明 |
+| modelPath | string | 实体类生成路径 |
+| servicePath | string | 服务类生成路径 |
+| controllerPath | string | 控制器生成路径 |
+| clientIndexPath | string | 前端列表页路径 |
+| clientInfoPath | string | 前端详情页路径 |
+| clientServicePath | string | 前端服务文件路径 |
+| isCover | boolean | 是否覆盖已存在文件 |
+
+**列级配置:**
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| displayName | string | 列的显示名称 |
+| describe | string | 列的描述说明 |
+| csField | string | C# 字段名 |
+| isTableSelect | boolean | 是否作为查询条件 |
+| isImageId | boolean | 是否是图片ID字段 |
+| isTableColumnShow | boolean | 是否在表格中显示 |
+
+---
+
+## 六、扩展指南
+
+### 6.1 新增数据源
+
+#### 步骤 1:添加常量定义
+
+```csharp
+// MiaoYu.Core.CodeGenerator/Abstractions/DataSourceConstants.cs
+
+public static class DataSourceConstants
+{
+ public const string Admin = "Admin";
+ public const string MiaoYuChat = "MiaoYuChat";
+ public const string LiveForum = "LiveForum";
+
+ // 🆕 新增
+ public const string YourNewDatabase = "YourNewDatabase";
+}
+```
+
+#### 步骤 2:创建 Provider 实现
+
+```csharp
+// MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Providers/YourNewDataSourceProvider.cs
+
+using HZY.Framework.DependencyInjection.Attributes;
+using MiaoYu.Core.CodeGenerator.Abstractions;
+
+namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers;
+
+///
+/// 新数据源提供者
+///
+[Component]
+public class YourNewDataSourceProvider : IDataSourceProvider, IScopedDependency
+{
+ private readonly IRepository _repository;
+
+ public YourNewDataSourceProvider(IRepository repository)
+ {
+ _repository = repository;
+ }
+
+ public DataSourceConfig Config => new DataSourceConfig
+ {
+ DatabaseKey = DataSourceConstants.YourNewDatabase,
+ DisplayName = "新数据库",
+ EntityNamespace = typeof(YourRepositoryStartup).Namespace!,
+
+ // 路径模板配置
+ ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\Apps\\{EntityNamePlural}",
+ ServicePathTemplate = "{AppPath}\\ApplicationServices\\Apps\\YourPath",
+ ControllerPathTemplate = "{AppPath}\\Controllers\\Apps\\YourPath",
+ ClientIndexPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
+ ClientInfoPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
+ ClientServicePathTemplate = "{RootPath}\\admin-client\\src\\services\\apps\\{TableName}s",
+
+ // 模板路径
+ TemplatePath = "/wwwroot/code_generation/template/",
+
+ // 命名策略
+ NamingStrategy = EntityNamingStrategy.ToPascalCase,
+
+ // 路径模式
+ UsesPluralPath = true,
+
+ // 排序
+ Order = 3,
+
+ // 前缀配置(可选)
+ EnableEntityPrefix = false,
+ EntityPrefix = ""
+ };
+
+ public List GetTables()
+ {
+ var freeSqlTables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
+ return ConvertToDbTableInfoList(freeSqlTables);
+ }
+
+ public object GetDbContext() => _repository.GetContext()!;
+
+ private List ConvertToDbTableInfoList(List freeSqlTables)
+ {
+ var result = new List();
+ foreach (var table in freeSqlTables)
+ {
+ var dbTableInfo = new CoreDbTableInfo
+ {
+ DataBase = Config.DatabaseKey,
+ Schema = table.Schema,
+ Name = table.Name,
+ Type = table.Type.ToString(),
+ Comment = table.Comment,
+ Columns = table.Columns?.Select(c => new CoreDbColumnInfo
+ {
+ Name = c.Name,
+ Comment = c.Comment,
+ IsPrimary = c.IsPrimary,
+ IsIdentity = c.IsIdentity,
+ IsNullable = c.IsNullable,
+ Position = c.Position,
+ DbType = c.DbTypeTextFull,
+ CsType = c.CsType?.Name,
+ MaxLength = c.MaxLength
+ }).ToList()
+ };
+ result.Add(dbTableInfo);
+ }
+ return result;
+ }
+}
+```
+
+#### 步骤 3:自动注册
+
+由于 Provider 实现了 `IScopedDependency`,依赖注入系统会自动注册。
+
+`DataSourceManager` 会在构造函数中自动收集所有 Provider 实例。
+
+**无需手动配置,立即生效!** ✅
+
+### 6.2 自定义代码模板
+
+#### 6.2.1 模板文件位置
+
+```
+MiaoYu.Api.Admin/wwwroot/code_generation/
+├── template/ # Admin 数据源使用
+│ ├── tempModel.cshtml
+│ ├── tempService.cshtml
+│ ├── tempController.cshtml
+│ ├── tempClientIndex.cshtml
+│ ├── tempClientInfo.cshtml
+│ └── tempClientService.cshtml
+└── templatev4/ # MiaoYuChat 数据源使用
+ ├── tempModel.cshtml
+ ├── tempService.cshtml
+ └── ...
+```
+
+#### 6.2.2 模板变量
+
+```razor
+@model GenDbTableDto
+
+可用属性:
+- @Model.TableName // 表名
+- @Model.DataBase // 数据库标识
+- @Model.EntityName // 实体名
+- @Model.DisplayName // 显示名称
+- @Model.Remark // 备注
+- @Model.Namespace // 命名空间
+- @Model.ModelPath // 实体路径
+- @Model.ServicePath // 服务路径
+- @Model.ControllerPath // 控制器路径
+- @Model.TableInfos // 列集合
+
+列属性(TableInfo):
+- @col.ColumnName // 列名
+- @col.CsType // C# 类型
+- @col.DisplayName // 显示名称
+- @col.Describe // 描述
+- @col.IsPrimary // 是否主键
+- @col.IsIdentity // 是否自增
+- @col.IsNullable // 是否可空
+- @col.DatabaseColumnType // 数据库类型
+- @col.MaxLength // 最大长度
+```
+
+#### 6.2.3 模板示例
+
+**Entity 模板:**
+```razor
+@model GenDbTableDto
+using System.ComponentModel.DataAnnotations;
+
+namespace @Model.Namespace.Entities
+{
+ ///
+ /// @Model.DisplayName
+ ///
+ public class @Model.EntityName
+ {
+ @foreach(var col in Model.TableInfos)
+ {
+ ///
+ /// @col.Describe
+ ///
+ @if(col.IsPrimary)
+ {
+ [Key]
+ }
+ @if(!col.IsNullable && col.CsType == "string")
+ {
+ [Required]
+ }
+ public @col.CsType@(col.IsNullable && col.CsType != "string" ? "?" : "") @col.ColumnName { get; set; }
+
+ }
+ }
+}
+```
+
+### 6.3 修改路径规则
+
+编辑对应 Provider 的 `Config` 配置:
+
+```csharp
+public DataSourceConfig Config => new DataSourceConfig
+{
+ // 修改模板路径
+ ModelPathTemplate = "{RootPath}\\{Namespace}\\Models\\{EntityName}",
+
+ // 修改服务路径
+ ServicePathTemplate = "{AppPath}\\Services\\{EntityName}",
+
+ // 添加自定义占位符(需扩展 PathResolver)
+ // ...
+};
+```
+
+---
+
+## 七、常见问题
+
+### 7.1 缓存问题
+
+**Q:修改了数据库表结构,为什么代码生成器看不到变化?**
+
+A:表结构缓存了 20 分钟。解决方法:
+1. 等待 20 分钟自动过期
+2. 调用 `ClearCache()` 清除缓存
+3. 在低代码平台点击"同步表"按钮
+
+**Q:如何禁用缓存?**
+
+A:修改 `TableSchemaCache.cs`:
+```csharp
+private static readonly TimeSpan CACHE_DURATION = TimeSpan.FromSeconds(0); // 禁用缓存
+```
+
+### 7.2 路径问题
+
+**Q:生成的文件路径不正确怎么办?**
+
+A:检查以下几点:
+1. Provider 的 `EntityNamespace` 是否正确
+2. 路径模板中的占位符是否正确
+3. `PathResolver` 的 `RootPath` 计算逻辑
+
+**Q:如何修改生成路径?**
+
+A:编辑对应 Provider 的 `Config.ModelPathTemplate` 等配置。
+
+### 7.3 命名问题
+
+**Q:为什么有的表名是驼峰,有的保持原样?**
+
+A:这由 `NamingStrategy` 决定:
+- `ToPascalCase`:`sys_user` → `SysUser`
+- `KeepOriginal`:`T_User` → `T_User`
+
+**Q:如何统一命名规则?**
+
+A:修改对应 Provider 的 `Config.NamingStrategy`。
+
+### 7.4 模板问题
+
+**Q:如何自定义生成的代码格式?**
+
+A:编辑 `/wwwroot/code_generation/template/` 或 `templatev4/` 下的 `.cshtml` 文件。
+
+**Q:不同数据源如何使用不同模板?**
+
+A:在 Provider 的 `Config.TemplatePath` 中指定不同的模板目录。
+
+### 7.5 配置文件问题
+
+**Q:配置文件在哪里?**
+
+A:`CodeGenConfig/{DatabaseKey}/{TableName}.json`
+
+**Q:配置文件什么时候生成?**
+
+A:
+1. 调用 `AutoImprotProjectAsync` 自动导入时
+2. 手动调用 `SaveTableMetaConfigAsync` 时
+
+**Q:如何批量修改配置?**
+
+A:直接编辑对应的 JSON 文件,或者通过低代码平台的配置界面。
+
+### 7.6 多数据源问题
+
+**Q:同名表如何区分?**
+
+A:通过 `DataBase` 字段区分:
+- `{ tableName: "User", dataBase: "Admin" }`
+- `{ tableName: "User", dataBase: "MiaoYuChat" }`
+
+**Q:如何新增数据源?**
+
+A:参考 [6.1 新增数据源](#61-新增数据源)。
+
+### 7.7 性能问题
+
+**Q:查询表列表很慢怎么办?**
+
+A:
+1. 检查缓存是否生效(应该只有第一次慢)
+2. 检查数据库连接是否正常
+3. 考虑减少表的数量或优化数据库查询
+
+**Q:生成代码很慢怎么办?**
+
+A:
+1. 检查 Razor 模板是否过于复杂
+2. 考虑异步批量生成
+3. 优化模板逻辑
+
+---
+
+## 八、API 接口文档
+
+### 8.1 获取数据库列表
+
+```http
+GET /api/CodeGeneration/databases
+```
+
+**响应示例:**
+```json
+[
+ { "key": "Admin", "displayName": "后台管理系统" },
+ { "key": "MiaoYuChat", "displayName": "喵语AI聊天" }
+]
+```
+
+### 8.2 获取表列表
+
+```http
+POST /api/CodeGeneration/{size}/{page}
+Content-Type: application/json
+
+{
+ "tableName": "User",
+ "dataBase": "MiaoYuChat"
+}
+```
+
+**响应示例:**
+```json
+{
+ "total": 5,
+ "page": 1,
+ "size": 50,
+ "dataSource": [
+ {
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat",
+ "remark": "用户表"
+ }
+ ]
+}
+```
+
+### 8.3 生成代码
+
+```http
+POST /api/CodeGeneration/GetCodeAsync
+Content-Type: application/json
+
+{
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat",
+ "type": "MiaoYu.Models"
+}
+```
+
+**type 可选值:**
+- `MiaoYu.Models` - 实体类
+- `MiaoYu.Services.Admin` - 服务类
+- `MiaoYu.Controllers.Admin` - 控制器
+- `Client.Index` - 前端列表页
+- `Client.Info` - 前端详情页
+- `Client.Service` - 前端服务
+
+### 8.4 下载代码
+
+```http
+POST /api/CodeGeneration/DownloadAsync
+Content-Type: application/json
+
+{
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat",
+ "type": "MiaoYu.Models"
+}
+```
+
+### 8.5 下载所有代码
+
+```http
+POST /api/CodeGeneration/DownloadAllAsync
+Content-Type: application/json
+
+{
+ "type": "MiaoYu.Models"
+}
+```
+
+### 8.6 自动导入项目
+
+```http
+POST /api/CodeGeneration/AutoImprotProjectAsync
+Content-Type: application/json
+
+{
+ "tableName": "T_User",
+ "dataBase": "MiaoYuChat"
+}
+```
+
+---
+
+## 九、最佳实践
+
+### 9.1 使用建议
+
+1. **先同步表** - 在生成代码前,先在低代码平台同步表结构
+2. **配置路径** - 根据项目结构配置合适的路径模板
+3. **自定义模板** - 根据团队规范自定义代码模板
+4. **备份配置** - 定期备份 `CodeGenConfig/` 目录
+5. **版本控制** - 将配置文件纳入 Git 管理
+
+### 9.2 命名规范
+
+- **表名**:使用有意义的前缀(如 `T_`, `Sys_`)
+- **列名**:使用驼峰命名或下划线分隔
+- **实体类**:使用 PascalCase(如 `User`, `OrderItem`)
+- **服务类**:使用 `XXXService` 格式
+- **控制器**:使用 `XXXController` 格式
+
+### 9.3 性能优化
+
+1. **合理使用缓存** - 保持 20 分钟缓存,减少数据库查询
+2. **按需生成** - 不要一次性生成所有表的代码
+3. **异步处理** - 大批量生成时使用异步方法
+4. **压缩打包** - 批量下载时使用 ZIP 格式
+
+### 9.4 安全建议
+
+1. **权限控制** - 代码生成接口应限制管理员访问
+2. **路径验证** - 防止路径穿越攻击
+3. **文件覆盖** - 默认不覆盖已存在文件
+4. **备份重要文件** - 生成前备份可能被覆盖的文件
+
+---
+
+## 十、更新日志
+
+### v2.0 (2024-11-07)
+- ✅ 重构为多数据源架构
+- ✅ 支持 Provider 模式
+- ✅ 配置文件持久化(JSON)
+- ✅ 表结构缓存优化
+- ✅ 路径模板支持占位符
+- ✅ 命名策略可配置
+
+### v1.0 (之前版本)
+- ✅ 基础代码生成功能
+- ✅ 单数据源支持
+- ✅ Razor 模板引擎
+- ✅ 自动导入项目
+
+---
+
+## 十一、技术支持
+
+- **文档位置**:`/代码生成器架构说明.md`
+- **配置文件**:`/CodeGenConfig/`
+- **模板文件**:`/MiaoYu.Api.Admin/wwwroot/code_generation/`
+- **架构文档**:`/MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/README.md`
+
+---
+
+## 附录 A:目录结构
+
+```
+admin-server/
+├── MiaoYu.Api.Admin/ # API 主项目
+│ ├── ApplicationServices/
+│ │ └── DevelopmentTools/
+│ │ └── LowCode/
+│ │ ├── Providers/ # 数据源提供者
+│ │ │ ├── AdminDataSourceProvider.cs
+│ │ │ ├── MiaoYuChatDataSourceProvider.cs
+│ │ │ └── LiveForumDataSourceProvider.cs
+│ │ ├── Impl/
+│ │ │ ├── LowCodeTableService.cs
+│ │ │ └── LowCodeTableInfoService.cs
+│ │ └── README.md
+│ ├── Controllers/
+│ │ └── DevelopmentTools/
+│ │ └── CodeGenerationController.cs # 代码生成控制器
+│ └── wwwroot/
+│ └── code_generation/
+│ ├── template/ # Admin 模板
+│ └── templatev4/ # MiaoYuChat 模板
+│
+├── MiaoYu.Core.CodeGenerator/ # 代码生成器核心
+│ ├── Abstractions/ # 抽象接口
+│ │ ├── IDataSourceProvider.cs
+│ │ ├── DataSourceConfig.cs
+│ │ ├── DataSourceConstants.cs
+│ │ └── EntityNamingStrategy.cs
+│ ├── Core/ # 核心工具
+│ │ ├── DataSourceManager.cs
+│ │ ├── PathResolver.cs
+│ │ └── DataSourceExtensions.cs
+│ ├── Services/ # 核心服务
+│ │ ├── ICodeGenerationService.cs
+│ │ ├── CodeGenerationService.cs
+│ │ ├── IDatabaseTableService.cs
+│ │ ├── DatabaseTableService.cs
+│ │ ├── ITableMetaConfigService.cs
+│ │ ├── TableMetaConfigService.cs
+│ │ ├── ITableSchemaCache.cs
+│ │ └── TableSchemaCache.cs
+│ ├── Models/ # 数据模型
+│ └── CoreCodeGeneratorStartup.cs
+│
+├── CodeGenConfig/ # 配置文件目录
+│ ├── Admin/
+│ │ ├── SysUser.json
+│ │ └── ...
+│ ├── MiaoYuChat/
+│ │ ├── T_User.json
+│ │ └── ...
+│ └── LiveForum/
+│ └── ...
+│
+└── 代码生成器架构说明.md # 本文档
+```
+
+---
+
+## 附录 B:类图
+
+```
+┌─────────────────────────────────────────────────────────┐
+│ IDataSourceProvider │
+│ + Config: DataSourceConfig │
+│ + GetTables(): List │
+│ + GetDbContext(): object │
+└─────────────────────────────────────────────────────────┘
+ ▲
+ │ implements
+ ┌───────────────┼───────────────┐
+ │ │ │
+┌────────────────┐ ┌────────────────┐ ┌────────────────┐
+│ AdminDataSource│ │MiaoYuChatData │ │LiveForumData │
+│ Provider │ │SourceProvider │ │SourceProvider │
+└────────────────┘ └────────────────┘ └────────────────┘
+ │ │ │
+ └───────────────┼───────────────┘
+ │ manages
+ ↓
+ ┌───────────────────────────────┐
+ │ DataSourceManager │
+ │ + GetAllProviders() │
+ │ + GetProvider(key) │
+ │ + GetAllTables() │
+ └───────────────────────────────┘
+ │ uses
+ ↓
+ ┌───────────────────────────────┐
+ │ TableSchemaCache │
+ │ + GetAllTables() │
+ │ + RefreshCache() │
+ │ + ClearCache() │
+ └───────────────────────────────┘
+ │ uses
+ ↓
+ ┌───────────────────────────────┐
+ │ DatabaseTableService │
+ │ + GetAllTables() │
+ │ + MergeTableWithConfig() │
+ └───────────────────────────────┘
+ │ uses
+ ┌───────────────┴───────────────┐
+ ↓ ↓
+┌───────────────────┐ ┌───────────────────┐
+│ TableMetaConfig │ │ CodeGeneration │
+│ Service │ │ Service │
+│ + LoadConfig() │ │ + GenModelAsync() │
+│ + SaveConfig() │ │ + GenServiceAsync()│
+└───────────────────┘ └───────────────────┘
+```
+
+---
+
+**文档结束**
+
+如有疑问,请联系开发团队。
+
diff --git a/admin-server/代码生成器流程文档.md b/admin-server/代码生成器流程文档.md
new file mode 100644
index 0000000..c5ad5b1
--- /dev/null
+++ b/admin-server/代码生成器流程文档.md
@@ -0,0 +1,885 @@
+# 代码生成器架构与流程文档
+
+## 一、整体架构
+
+### 1.1 架构设计原则
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ 代码生成器核心架构 │
+├─────────────────────────────────────────────────────────────┤
+│ │
+│ API层 (MiaoYu.Api.Admin) │
+│ ├── Controllers (对外接口) │
+│ ├── Providers (数据源提供者实现) │
+│ │ ├── AdminDataSourceProvider │
+│ │ ├── MiaoYuChatDataSourceProvider │
+│ │ └── LiveForumDataSourceProvider (待实现) │
+│ └── Services (业务逻辑) │
+│ ├── LowCodeTableService (表列表管理) │
+│ └── LowCodeTableInfoService (列配置管理) │
+│ │
+│ ───────────────────────────────────────────────────── │
+│ │
+│ 核心层 (MiaoYu.Core.CodeGenerator) │
+│ ├── Abstractions (抽象接口) │
+│ │ ├── IDataSourceProvider (数据源提供者接口) │
+│ │ ├── DataSourceConfig (数据源配置) │
+│ │ └── EntityNamingStrategy (命名策略枚举) │
+│ ├── Core (核心逻辑) │
+│ │ ├── DataSourceManager (数据源管理器) │
+│ │ └── PathResolver (路径解析器) │
+│ ├── Services (核心服务) │
+│ │ ├── CodeGenerationService (代码生成服务) │
+│ │ ├── DatabaseTableService (数据库表服务) │
+│ │ ├── TableMetaConfigService (表元信息配置服务) │
+│ │ └── TableSchemaCache (表结构缓存) │
+│ └── Models (数据模型) │
+│ ├── GenDbTableDto (统一的表模型) │
+│ ├── LowCodeTableInfo (列信息模型) │
+│ ├── DbTableInfo (数据库表信息) │
+│ └── TableMetaConfig (表元信息配置) │
+│ │
+└─────────────────────────────────────────────────────────────┘
+```
+
+### 1.2 核心设计模式
+
+1. **Provider 模式**: 支持多数据源扩展
+2. **策略模式**: 命名策略可配置(PascalCase、KeepOriginal)
+3. **模板方法模式**: 统一的代码生成流程
+4. **缓存模式**: 表结构缓存,提升性能
+5. **配置驱动**: 路径、命名等通过配置文件管理
+
+---
+
+## 二、核心流程详解
+
+### 2.1 启动初始化流程
+
+```
+应用启动
+ ↓
+注册数据源提供者 (AdminDataSourceProvider, MiaoYuChatDataSourceProvider)
+ ↓
+DataSourceManager 收集所有 IDataSourceProvider 实例
+ ↓
+TableSchemaCache 从所有数据源加载表结构
+ ↓
+缓存有效期:20分钟
+```
+
+**关键代码位置**:
+- `MiaoYu.Core.CodeGenerator/CoreCodeGeneratorStartup.cs` - 核心模块注册
+- `MiaoYu.Core.CodeGenerator/Core/DataSourceManager.cs` - 数据源管理
+- `MiaoYu.Core.CodeGenerator/Services/TableSchemaCache.cs` - 缓存服务
+
+---
+
+### 2.2 获取表列表流程
+
+```
+前端请求 GET /api/v1/admin/LowCodeTable/list?dataBase=Admin
+ ↓
+LowCodeTableService.FindListAsync()
+ ↓
+调用 DatabaseTableService.GetAllTables()
+ ↓
+ ├─→ TableSchemaCache.GetAllTables() (从缓存获取原始表信息)
+ │ ↓
+ │ 遍历所有 DataSourceProvider 获取表结构
+ │ ↓
+ │ 返回 List
+ │
+ ↓
+遍历每个 DbTableInfo,调用 MergeTableWithConfig()
+ ↓
+ ├─→ 获取数据源配置 (DataSourceConfig)
+ ├─→ 应用命名策略生成默认 EntityName
+ │ 例如: "song_likes" → "SongLikes" (ToPascalCase)
+ ├─→ 加载 TableMetaConfig (如果存在)
+ │ 路径: configs/{dataBase}/{tableName}.json
+ ├─→ 合并配置:配置文件中的值覆盖默认值
+ └─→ 返回 GenDbTableDto (统一的表模型)
+ ↓
+过滤 (dataBase, tableName 等条件)
+ ↓
+分页返回
+```
+
+**数据转换链**:
+```
+DbTableInfo (数据库原始信息)
+ ↓
++ DataSourceConfig (数据源配置)
+ ↓
++ TableMetaConfig (用户自定义配置,可选)
+ ↓
+= GenDbTableDto (最终统一模型)
+```
+
+**关键文件**:
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableService.cs`
+- `MiaoYu.Core.CodeGenerator/Services/DatabaseTableService.cs`
+
+---
+
+### 2.3 修改列配置流程
+
+```
+前端请求 PUT /api/v1/admin/LowCodeTableInfo/change
+ ↓
+LowCodeTableInfoService.ChangeAsync(List)
+ ↓
+清除缓存: DatabaseTableService.ClearAllTablesByCache()
+ ↓
+按表分组处理
+ ↓
+对每个表:
+ ├─→ 获取 LowCodeTable (从数据库,用于获取 tableName 和 dataBase)
+ ├─→ 从 DatabaseTableService.GetAllTables() 获取最新的表信息
+ ├─→ 查找目标表
+ ├─→ 更新列配置 (DisplayName, Describe, CsField, IsTableSelect 等)
+ └─→ 调用 SaveTableMetaConfigAsync()
+ ↓
+ TableMetaConfigService.SaveConfigAsync()
+ ↓
+ 保存到: configs/{dataBase}/{tableName}.json
+ ↓
+ 文件内容示例:
+ {
+ "DisplayName": "歌曲点赞记录",
+ "EntityName": "SongLike",
+ "Remark": "记录用户对歌曲的点赞",
+ "Columns": {
+ "SongId": {
+ "DisplayName": "歌曲ID",
+ "Describe": "被点赞的歌曲ID",
+ "CsField": "SongId",
+ ...
+ }
+ }
+ }
+```
+
+**配置文件结构**:
+```json
+{
+ "DisplayName": "显示名称",
+ "EntityName": "实体类名",
+ "Remark": "备注说明",
+ "ModelPath": "模型路径",
+ "ServicePath": "服务路径",
+ "ControllerPath": "控制器路径",
+ "ClientIndexPath": "前端索引页路径",
+ "ClientInfoPath": "前端详情页路径",
+ "ClientServicePath": "前端服务路径",
+ "IsCover": true,
+ "Columns": {
+ "ColumnName1": {
+ "DisplayName": "列显示名",
+ "Describe": "列描述",
+ "CsField": "C#字段名",
+ "IsTableSelect": true,
+ "IsImageId": false,
+ "IsTableColumnShow": true
+ }
+ }
+}
+```
+
+**关键文件**:
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableInfoService.cs`
+- `MiaoYu.Core.CodeGenerator/Services/TableMetaConfigService.cs`
+
+---
+
+### 2.4 代码生成流程
+
+```
+前端请求 POST /api/v1/admin/CodeGeneration/getCode
+参数: { tableName: "song_likes", fileTypeEnum: 1 (Model) }
+ ↓
+CodeGenerationController.GetCodeAsync()
+ ↓
+CoreICodeGenerationService.GetCodeAsync()
+ ↓
+CodeGenerationService.GetCodeAsync()
+ ↓
+1. 获取表信息
+ ├─→ GetGenContextDtoByTableName("song_likes")
+ ├─→ DatabaseTableService.GetAllTables()
+ └─→ 找到对应的 GenDbTableDto
+ ↓
+2. 确定数据源和配置
+ ├─→ DataSourceManager.GetProvider(dataBase)
+ └─→ 获取 DataSourceConfig (包含模板路径、命名策略等)
+ ↓
+3. 解析路径
+ ├─→ PathResolver.ResolvePath(template, config, tableName)
+ ├─→ 替换占位符:
+ │ {RootPath} → 项目根路径
+ │ {AppPath} → 应用路径
+ │ {EntityName} → SongLike (应用命名策略)
+ │ {EntityNamePlural} → SongLikes
+ │ {TableName} → song_likes
+ └─→ 生成完整路径
+ ↓
+4. 渲染模板
+ ├─→ 根据 fileTypeEnum 选择模板文件
+ │ FileTypeEnum.Model → tempModel.cshtml
+ │ FileTypeEnum.Service → tempService.cshtml
+ │ FileTypeEnum.Controller → tempController.cshtml
+ │ 等等
+ ├─→ 加载 Razor 模板
+ ├─→ 传入 Model: GenDbTableDto
+ └─→ RazorViewRender.RenderToStringAsync()
+ ↓
+5. 返回生成的代码
+ ├─→ ModelCode: "public class SongLike { ... }"
+ ├─→ FilePath: "D:\\...\\Entities\\Apps\\SongLikes"
+ └─→ FileName: "SongLike.cs"
+```
+
+**模板渲染过程**:
+```
+tempModel.cshtml (Razor模板)
+ ↓
+@model GenDbTableDto
+ ↓
+访问模型属性:
+ @Model.EntityName → "SongLike"
+ @Model.DisplayName → "歌曲点赞记录"
+ @Model.TableName → "song_likes"
+ @Model.TableInfos → List
+ ↓
+遍历列信息:
+ @foreach (var item in tableInfos)
+ {
+ public @GetType(item) @item.ColumnName { get; set; }
+ }
+ ↓
+生成最终代码
+```
+
+**关键文件**:
+- `MiaoYu.Api.Admin/Controllers/DevelopmentTools/CodeGenerationController.cs`
+- `MiaoYu.Core.CodeGenerator/Services/CodeGenerationService.cs`
+- `MiaoYu.Core.CodeGenerator/Core/PathResolver.cs`
+- `MiaoYu.Api.Admin/wwwroot/code_generation/template/*.cshtml`
+
+---
+
+## 三、关键组件详解
+
+### 3.1 DataSourceManager (数据源管理器)
+
+**职责**:
+- 收集所有 `IDataSourceProvider` 实现
+- 提供按 key 查询特定数据源的能力
+- 聚合所有数据源的表信息
+
+**核心方法**:
+```csharp
+public IDataSourceProvider? GetProvider(string key)
+public List GetAllTables()
+```
+
+**使用场景**:
+- 初始化时收集所有数据源
+- 生成代码时根据 dataBase 获取对应的 Provider 和配置
+
+---
+
+### 3.2 DatabaseTableService (数据库表服务)
+
+**职责**:
+- 管理表结构信息
+- 合并数据库 schema 和用户配置
+- 提供统一的表数据模型
+
+**核心方法**:
+```csharp
+// 获取所有表(已合并配置)
+public List GetAllTables()
+
+// 合并表结构和配置文件信息
+private GenDbTableDto MergeTableWithConfig(DbTableInfo schemaTable)
+```
+
+**合并逻辑**:
+1. 创建 `GenDbTableDto`,设置基础信息
+2. 应用命名策略生成默认 `EntityName`
+3. 从配置文件加载 `TableMetaConfig`
+4. 用配置文件中的值覆盖默认值(如果配置存在且有值)
+5. 合并列级配置
+
+---
+
+### 3.3 TableMetaConfigService (表元信息配置服务)
+
+**职责**:
+- 加载和保存表的元信息配置
+- 管理配置文件(JSON格式)
+
+**配置文件路径规则**:
+```
+configs/{dataBase}/{tableName}.json
+```
+
+**核心方法**:
+```csharp
+public TableMetaConfig? LoadConfig(string dataBase, string tableName)
+public void SaveConfigAsync(string dataBase, string tableName, TableMetaConfig config)
+```
+
+**使用场景**:
+- 用户修改列配置后保存
+- 加载表信息时读取用户自定义配置
+
+---
+
+### 3.4 PathResolver (路径解析器)
+
+**职责**:
+- 解析路径模板中的占位符
+- 应用命名策略转换表名为实体名
+
+**支持的占位符**:
+- `{RootPath}`: 项目根路径
+- `{AppPath}`: 应用路径
+- `{Namespace}`: 命名空间
+- `{EntityName}`: 实体名(单数,应用命名策略)
+- `{EntityNamePlural}`: 实体名(复数)
+- `{TableName}`: 原始表名
+
+**命名策略**:
+```csharp
+public enum EntityNamingStrategy
+{
+ KeepOriginal, // 保持原样
+ ToPascalCase // 转为 PascalCase (song_likes → SongLikes)
+}
+```
+
+**转换规则**:
+```csharp
+private static string ConvertToPascalCase(string input)
+{
+ // "song_likes" → ["song", "likes"]
+ var words = input.Split('_', '-');
+
+ // 首字母大写: ["Song", "Likes"]
+ foreach (var word in words)
+ {
+ result.Append(char.ToUpper(word[0]));
+ result.Append(word.Substring(1).ToLower());
+ }
+
+ // 结果: "SongLikes"
+ return result.ToString();
+}
+```
+
+---
+
+### 3.5 TableSchemaCache (表结构缓存)
+
+**职责**:
+- 缓存所有数据源的表结构信息
+- 减少数据库查询次数
+- 提供缓存刷新机制
+
+**缓存策略**:
+```csharp
+private const int CacheDurationMinutes = 20;
+```
+
+**核心方法**:
+```csharp
+public List GetAllTables()
+public void ClearCache()
+```
+
+**缓存刷新时机**:
+- 应用启动时自动加载
+- 缓存过期(20分钟)
+- 用户手动清除(修改列配置后)
+
+---
+
+## 四、数据源配置详解
+
+### 4.1 DataSourceConfig 配置项
+
+```csharp
+public class DataSourceConfig
+{
+ // 数据库标识键
+ public string DatabaseKey { get; set; }
+
+ // 显示名称
+ public string DisplayName { get; set; }
+
+ // 实体命名空间
+ public string EntityNamespace { get; set; }
+
+ // 路径模板(支持占位符)
+ public string ModelPathTemplate { get; set; }
+ public string ServicePathTemplate { get; set; }
+ public string ControllerPathTemplate { get; set; }
+ public string ClientIndexPathTemplate { get; set; }
+ public string ClientInfoPathTemplate { get; set; }
+ public string ClientServicePathTemplate { get; set; }
+
+ // 模板路径
+ public string TemplatePath { get; set; }
+
+ // 命名策略
+ public EntityNamingStrategy NamingStrategy { get; set; }
+
+ // 实体前缀配置
+ public bool EnableEntityPrefix { get; set; }
+ public string EntityPrefix { get; set; }
+
+ // 路径是否使用复数形式
+ public bool UsesPluralPath { get; set; }
+
+ // 显示顺序
+ public int Order { get; set; }
+}
+```
+
+### 4.2 示例:Admin 数据源配置
+
+```csharp
+public DataSourceConfig Config => new DataSourceConfig
+{
+ DatabaseKey = "Admin",
+ DisplayName = "后台管理系统",
+ EntityNamespace = "MiaoYu.Repository.Admin.Entities",
+
+ // 模型路径: D:\...\MiaoYu.Repository.Admin\Entities\Apps\SongLikes
+ ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\Apps\\{EntityNamePlural}",
+
+ // 服务路径: D:\...\MiaoYu.Api.Admin\ApplicationServices\Apps\SongLikes
+ ServicePathTemplate = "{AppPath}\\ApplicationServices\\Apps\\{EntityNamePlural}",
+
+ // 控制器路径
+ ControllerPathTemplate = "{AppPath}\\Controllers\\Apps\\{EntityNamePlural}",
+
+ // 前端路径
+ ClientIndexPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
+ ClientInfoPathTemplate = "{RootPath}\\admin-client\\src\\views\\apps\\{TableName}s",
+ ClientServicePathTemplate = "{RootPath}\\admin-client\\src\\services\\apps\\{TableName}s",
+
+ // 模板路径
+ TemplatePath = "/wwwroot/code_generation/template/",
+
+ // 命名策略:转为 PascalCase
+ NamingStrategy = EntityNamingStrategy.ToPascalCase,
+
+ // 不使用前缀
+ EnableEntityPrefix = false,
+ EntityPrefix = "",
+
+ // 路径使用复数
+ UsesPluralPath = true,
+
+ Order = 1
+};
+```
+
+---
+
+## 五、Razor 模板详解
+
+### 5.1 模板文件结构
+
+```
+wwwroot/code_generation/
+├── template/ # 模板 V1
+│ ├── _ViewImports.cshtml # Razor 视图导入(重要!)
+│ ├── tempModel.cshtml # 实体模型模板
+│ ├── tempService.cshtml # 服务模板
+│ ├── tempController.cshtml # 控制器模板
+│ ├── tempIndex.cshtml # 前端索引页模板
+│ ├── tempInfo.cshtml # 前端详情页模板
+│ └── tempService_admin.cshtml # 前端服务模板
+└── templatev4/ # 模板 V4(新版本)
+ ├── _ViewImports.cshtml
+ ├── tempModel.cshtml
+ └── ...
+```
+
+### 5.2 _ViewImports.cshtml 的重要性
+
+**作用**: 定义 Razor 模板的全局 using 指令
+
+```cshtml
+@* 代码生成器模型命名空间 *@
+@using MiaoYu.Core.CodeGenerator.Models
+```
+
+**为什么需要**:
+1. 解决类型冲突:`GenDbTableDto` 在多个命名空间存在
+2. 明确指定模板使用 Core 层的模型
+3. 避免 Razor 编译时的类型歧义错误
+
+**历史问题回顾**:
+```
+错误: The model item is of type 'MiaoYu.Core.CodeGenerator.Models.GenDbTableDto',
+ but this ViewDataDictionary requires 'MiaoYu.Shared.Admin.Models.LowCodes.GenDbTableDto'
+
+原因: 缺少 _ViewImports.cshtml,Razor 引擎使用了错误的类型
+
+解决: 创建 _ViewImports.cshtml 明确指定使用 Core 层的模型
+```
+
+### 5.3 模板示例:tempModel.cshtml
+
+```cshtml
+@model GenDbTableDto
+@{
+ var className = Model.EntityName; // "SongLike"
+ var classNameRemark = Model.DisplayName; // "歌曲点赞记录"
+
+ // 需要忽略的字段
+ var ignores = new string[] {
+ "Id", "CreationTime", "CreatorUserId",
+ "LastModificationTime", "LastModifierUserId",
+ "DeletionTime", "DeleterUserId",
+ "IsDeleted", "TenantId"
+ };
+
+ // 过滤并排序列
+ var tableInfos = Model.TableInfos
+ .Where(w => !ignores.Contains(w.ColumnName))
+ .OrderBy(w => w.Position)
+ .ToList();
+}
+
+@functions
+{
+ // 根据列信息获取 C# 类型
+ string GetType(LowCodeTableInfo appTableInfo)
+ {
+ switch (appTableInfo.DatabaseColumnType)
+ {
+ case "uniqueidentifier":
+ return appTableInfo.IsNullable ? "Guid?" : "Guid";
+ case "int":
+ return appTableInfo.IsNullable ? "int?" : "int";
+ case "bigint":
+ return appTableInfo.IsNullable ? "long?" : "long";
+ case "datetime":
+ return appTableInfo.IsNullable ? "DateTime?" : "DateTime";
+ // ... 更多类型映射
+ default:
+ // 使用数据库提供的 C# 类型
+ return appTableInfo.IsNullable
+ ? appTableInfo.CsType + "?"
+ : appTableInfo.CsType;
+ }
+ }
+}
+
+
+namespace @Model.EntityNamespace.Entities.Apps;
+
+///
+/// @classNameRemark
+///
+[EntityDescription(FieldIgnored = true)]
+[Table("@Model.TableName")]
+public class @className : DefaultEntityV4
+{
+ @foreach (var item in tableInfos)
+ {
+
+ ///
+ /// @(item.DisplayName ?? item.ColumnName) => 备注: @(item.Describe ?? item.ColumnName)
+ ///
+ public @GetType(item) @item.ColumnName { get; set; }
+
+ }
+}
+
+```
+
+---
+
+## 六、常见问题与解决方案
+
+### 6.1 生成的类名为空
+
+**现象**:
+```csharp
+[Table("")]
+public class : DefaultEntityV4
+```
+
+**原因**:
+- `GenDbTableDto.EntityName` 和 `TableName` 为 null
+- `DatabaseTableService` 未提供默认值
+
+**解决方案**:
+- 在 `MergeTableWithConfig` 中为 `EntityName` 提供默认值
+- 使用 `PathResolver.GetEntityName()` 应用命名策略
+- 从 `schemaTable.Name` 转换为 PascalCase
+
+### 6.2 Razor 模板类型错误
+
+**现象**:
+```
+InvalidOperationException: The model item is of type 'X' but requires type 'Y'
+```
+
+**原因**:
+- 缺少 `_ViewImports.cshtml`
+- 类型在多个命名空间存在,导致歧义
+
+**解决方案**:
+- 创建 `_ViewImports.cshtml`
+- 明确指定: `@using MiaoYu.Core.CodeGenerator.Models`
+
+### 6.3 属性访问错误
+
+**现象**:
+```
+'DbColumnInfo' does not contain a definition for 'DbTypeText'
+'string' does not contain a definition for 'Name'
+```
+
+**原因**:
+- 模板中使用了不存在的属性名
+- 属性类型已更改(如 `CsType` 从 `Type` 改为 `string`)
+
+**解决方案**:
+- 检查模型定义,使用正确的属性名
+- `DbTypeText` → `DatabaseColumnType`
+- `CsType.Name` → `CsType` (因为已是字符串)
+
+### 6.4 数据库过滤不生效
+
+**现象**:
+- 选择 "Admin" 数据库,仍显示所有数据库的表
+
+**原因**:
+- `LowCodeTableService.FindListAsync()` 未应用 `dataBase` 过滤
+
+**解决方案**:
+```csharp
+if (!string.IsNullOrWhiteSpace(pagingSearchInput.Search.DataBase))
+{
+ filteredTables = filteredTables.Where(t =>
+ t.DataBase == pagingSearchInput.Search.DataBase);
+}
+```
+
+---
+
+## 七、扩展指南
+
+### 7.1 添加新的数据源
+
+**步骤**:
+
+1. **创建 Provider 实现**:
+
+```csharp
+[Component]
+public class LiveForumDataSourceProvider : IDataSourceProvider, IScopedDependency
+{
+ private readonly IRepository _repository;
+
+ public LiveForumDataSourceProvider(IRepository repository)
+ {
+ _repository = repository;
+ }
+
+ public DataSourceConfig Config => new DataSourceConfig
+ {
+ DatabaseKey = DataSourceConstants.LiveForum,
+ DisplayName = "直播论坛",
+ EntityNamespace = "MiaoYu.Repository.LiveForum.Entities",
+ ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\{EntityNamePlural}",
+ // ... 其他配置
+ NamingStrategy = EntityNamingStrategy.ToPascalCase,
+ Order = 3
+ };
+
+ public List GetTables()
+ {
+ var freeSqlTables = _repository.UnitOfWork.FreeSqlOrm
+ .DbFirst.GetTablesByDatabase();
+ return ConvertToDbTableInfoList(freeSqlTables);
+ }
+
+ public object GetDbContext() => _repository.GetContext()!;
+
+ private List ConvertToDbTableInfoList(/* ... */)
+ {
+ // 转换逻辑
+ }
+}
+```
+
+2. **添加常量**:
+
+```csharp
+// MiaoYu.Core.CodeGenerator/Abstractions/DataSourceConstants.cs
+public static class DataSourceConstants
+{
+ public const string Admin = "Admin";
+ public const string MiaoYuChat = "MiaoYuChat";
+ public const string LiveForum = "LiveForum"; // 新增
+}
+```
+
+3. **自动注册**:
+ - 使用 `[Component]` 特性,框架会自动注册
+ - `DataSourceManager` 会自动发现并收集
+
+### 7.2 添加新的命名策略
+
+**步骤**:
+
+1. **扩展枚举**:
+
+```csharp
+public enum EntityNamingStrategy
+{
+ KeepOriginal,
+ ToPascalCase,
+ ToSnakeCase // 新增: PascalCase → snake_case
+}
+```
+
+2. **实现转换逻辑**:
+
+```csharp
+// PathResolver.cs
+public string GetEntityName(string tableName, DataSourceConfig config)
+{
+ var baseName = config.NamingStrategy switch
+ {
+ EntityNamingStrategy.ToPascalCase => ConvertToPascalCase(tableName),
+ EntityNamingStrategy.ToSnakeCase => ConvertToSnakeCase(tableName),
+ _ => tableName
+ };
+ // ...
+}
+
+private static string ConvertToSnakeCase(string input)
+{
+ // 实现 PascalCase → snake_case 转换
+}
+```
+
+### 7.3 自定义模板
+
+**步骤**:
+
+1. **创建新模板**: 复制现有模板并修改
+2. **定义模板路径**: 在 `DataSourceConfig` 中配置
+3. **添加文件类型**: 扩展 `FileTypeEnum`
+4. **实现生成逻辑**: 在 `CodeGenerationService` 中添加对应处理
+
+---
+
+## 八、性能优化建议
+
+### 8.1 缓存策略
+
+1. **表结构缓存**: 20 分钟有效期,避免频繁查询数据库
+2. **配置文件缓存**: 考虑使用 `MemoryCache` 缓存 JSON 配置
+3. **模板编译缓存**: Razor 引擎已内置缓存
+
+### 8.2 并发处理
+
+1. **读写分离**: 读取表结构和生成代码不影响数据库写入
+2. **异步处理**: 所有 IO 操作使用 `async/await`
+3. **并行生成**: 批量生成时可使用 `Parallel.ForEach`
+
+---
+
+## 九、总结
+
+### 9.1 核心优势
+
+1. **多数据源支持**: 轻松扩展新数据源
+2. **配置驱动**: 灵活的路径和命名策略
+3. **模板化**: Razor 模板,易于定制
+4. **文件化配置**: JSON 配置文件,支持版本控制
+5. **缓存优化**: 减少数据库查询,提升性能
+
+### 9.2 设计亮点
+
+1. **Provider 模式**: 实现数据源的插件化
+2. **双层合并**: 数据库 schema + 用户配置
+3. **命名策略**: 智能转换表名为类名
+4. **统一模型**: `GenDbTableDto` 作为中间层
+5. **路径解析**: 占位符系统,灵活配置
+
+### 9.3 后续改进方向
+
+1. **LiveForum 数据源**: 补充第三个数据源实现
+2. **模板管理**: 支持在线编辑和版本管理
+3. **增量生成**: 只生成变更的部分
+4. **代码预览**: 生成前预览代码
+5. **批量操作**: 支持批量表生成
+
+---
+
+## 十、参考资料
+
+### 10.1 核心文件清单
+
+**API 层**:
+- `MiaoYu.Api.Admin/Controllers/DevelopmentTools/CodeGenerationController.cs`
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableService.cs`
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Impl/LowCodeTableInfoService.cs`
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Providers/AdminDataSourceProvider.cs`
+- `MiaoYu.Api.Admin/ApplicationServices/DevelopmentTools/LowCode/Providers/MiaoYuChatDataSourceProvider.cs`
+
+**核心层**:
+- `MiaoYu.Core.CodeGenerator/CoreCodeGeneratorStartup.cs`
+- `MiaoYu.Core.CodeGenerator/Core/DataSourceManager.cs`
+- `MiaoYu.Core.CodeGenerator/Core/PathResolver.cs`
+- `MiaoYu.Core.CodeGenerator/Services/CodeGenerationService.cs`
+- `MiaoYu.Core.CodeGenerator/Services/DatabaseTableService.cs`
+- `MiaoYu.Core.CodeGenerator/Services/TableMetaConfigService.cs`
+- `MiaoYu.Core.CodeGenerator/Services/TableSchemaCache.cs`
+
+**模板**:
+- `MiaoYu.Api.Admin/wwwroot/code_generation/template/_ViewImports.cshtml`
+- `MiaoYu.Api.Admin/wwwroot/code_generation/template/tempModel.cshtml`
+
+### 10.2 配置文件示例
+
+**表元信息配置**: `configs/Admin/song_likes.json`
+```json
+{
+ "DisplayName": "歌曲点赞记录",
+ "EntityName": "SongLike",
+ "Remark": "记录用户对歌曲的点赞行为",
+ "IsCover": true,
+ "Columns": {
+ "SongId": {
+ "DisplayName": "歌曲ID",
+ "Describe": "被点赞的歌曲标识",
+ "CsField": "SongId",
+ "IsTableSelect": true,
+ "IsTableColumnShow": true
+ }
+ }
+}
+```
+
+---
+
+**文档版本**: v1.0
+**最后更新**: 2025-11-07
+**维护者**: AI Assistant
+