|
| 1 | +@page "/database-connection/table-detail/{ConnectionId}/{TableName}" |
| 2 | +@using Text2Sql.Net.Repositories.Text2Sql.DatabaseSchema |
| 3 | +@using Text2Sql.Net.Domain.Interface |
| 4 | +@inject ISchemaTrainingService SchemaTrainingService |
| 5 | +@inject MessageService MessageService |
| 6 | +@inject NavigationManager NavigationManager |
| 7 | + |
| 8 | +<PageContainer Title="@($"表详情 - {TableName}")"> |
| 9 | + <Extra> |
| 10 | + <Space> |
| 11 | + <SpaceItem> |
| 12 | + <Button Type="@ButtonType.Default" OnClick="@NavigateToTableList"> |
| 13 | + <Icon Type="@IconType.Outline.ArrowLeft" /> |
| 14 | + 返回表列表 |
| 15 | + </Button> |
| 16 | + </SpaceItem> |
| 17 | + <SpaceItem> |
| 18 | + <Button Type="@ButtonType.Default" OnClick="@NavigateToConnection"> |
| 19 | + <Icon Type="@IconType.Outline.Database" /> |
| 20 | + 连接详情 |
| 21 | + </Button> |
| 22 | + </SpaceItem> |
| 23 | + </Space> |
| 24 | + </Extra> |
| 25 | + <ChildContent> |
| 26 | + <Card Loading="@_loading"> |
| 27 | + <ChildContent> |
| 28 | + @if (_tableInfo != null) |
| 29 | + { |
| 30 | + <!-- 基本信息卡片 --> |
| 31 | + <Card Title="基本信息" Size="@AntSizeLDSType.Small" Style="margin-bottom: 16px;"> |
| 32 | + <ChildContent> |
| 33 | + <Descriptions Size="@AntSizeLDSType.Small" Bordered="true" Column="2"> |
| 34 | + <DescriptionsItem Title="表名" Span="1"> |
| 35 | + <Text Strong>@_tableInfo.TableName</Text> |
| 36 | + </DescriptionsItem> |
| 37 | + <DescriptionsItem Title="列数" Span="1"> |
| 38 | + <Tag Color="blue">@_tableInfo.Columns.Count 列</Tag> |
| 39 | + </DescriptionsItem> |
| 40 | + <DescriptionsItem Title="主键数" Span="1"> |
| 41 | + @{ |
| 42 | + var primaryKeyCount = _tableInfo.Columns.Count(c => c.IsPrimaryKey); |
| 43 | + } |
| 44 | + <Tag Color="@(primaryKeyCount > 0 ? "gold" : "default")">@primaryKeyCount 个</Tag> |
| 45 | + </DescriptionsItem> |
| 46 | + <DescriptionsItem Title="外键数" Span="1"> |
| 47 | + @{ |
| 48 | + var foreignKeyCount = _tableInfo.ForeignKeys?.Count ?? 0; |
| 49 | + } |
| 50 | + <Tag Color="@(foreignKeyCount > 0 ? "green" : "default")">@foreignKeyCount 个</Tag> |
| 51 | + </DescriptionsItem> |
| 52 | + <DescriptionsItem Title="描述" Span="2"> |
| 53 | + @(_tableInfo.Description ?? "无描述") |
| 54 | + </DescriptionsItem> |
| 55 | + </Descriptions> |
| 56 | + </ChildContent> |
| 57 | + </Card> |
| 58 | + |
| 59 | + <!-- 外键关系卡片 --> |
| 60 | + @if (_tableInfo.ForeignKeys?.Any() == true) |
| 61 | + { |
| 62 | + <Card Title="外键关系" Size="@AntSizeLDSType.Small" Style="margin-bottom: 16px;"> |
| 63 | + <ChildContent> |
| 64 | + @foreach (var fk in _tableInfo.ForeignKeys) |
| 65 | + { |
| 66 | + <div style="padding: 8px; border: 1px solid #f0f0f0; border-radius: 6px; margin-bottom: 8px;"> |
| 67 | + <div style="display: flex; align-items: center; margin-bottom: 4px;"> |
| 68 | + <Icon Type="@IconType.Outline.Link" Style="margin-right: 8px; color: #1890ff;" /> |
| 69 | + <Text Strong>@fk.ForeignKeyName</Text> |
| 70 | + </div> |
| 71 | + <div style="color: #666; font-size: 14px;"> |
| 72 | + @fk.RelationshipDescription |
| 73 | + </div> |
| 74 | + </div> |
| 75 | + } |
| 76 | + </ChildContent> |
| 77 | + </Card> |
| 78 | + } |
| 79 | + |
| 80 | + <!-- 列信息卡片 --> |
| 81 | + <Card Title="@($"列信息 ({_tableInfo.Columns.Count} 列)")" Size="@AntSizeLDSType.Small"> |
| 82 | + <ChildContent> |
| 83 | + <Table TItem="ColumnInfo" |
| 84 | + DataSource="@_tableInfo.Columns" |
| 85 | + Size="@TableSize.Small" |
| 86 | + Bordered="true" |
| 87 | + PageSize="15" |
| 88 | + Responsive="true"> |
| 89 | + <AntDesign.Column TData="string" DataIndex="@nameof(ColumnInfo.ColumnName)" Title="列名" Width="200"> |
| 90 | + <div style="display: flex; align-items: center;"> |
| 91 | + <Text Strong="@context.IsPrimaryKey" Type="@(context.IsPrimaryKey ? TextElementType.Warning : null)"> |
| 92 | + @context.ColumnName |
| 93 | + </Text> |
| 94 | + @if (context.IsPrimaryKey) |
| 95 | + { |
| 96 | + <Icon Type="@IconType.Outline.Key" Style="margin-left: 8px; color: #fa8c16;" /> |
| 97 | + } |
| 98 | + </div> |
| 99 | + </AntDesign.Column> |
| 100 | + <AntDesign.Column TData="string" DataIndex="@nameof(ColumnInfo.DataType)" Title="数据类型" Width="150"> |
| 101 | + <Tag Color="@GetDataTypeColor(context.DataType)">@context.DataType</Tag> |
| 102 | + </AntDesign.Column> |
| 103 | + <AntDesign.Column TData="bool" DataIndex="@nameof(ColumnInfo.IsNullable)" Title="可空" Width="80" Align="@ColumnAlign.Center"> |
| 104 | + @if (context.IsNullable) |
| 105 | + { |
| 106 | + <Tag Color="success">是</Tag> |
| 107 | + } |
| 108 | + else |
| 109 | + { |
| 110 | + <Tag Color="error">否</Tag> |
| 111 | + } |
| 112 | + </AntDesign.Column> |
| 113 | + <AntDesign.Column TData="bool" DataIndex="@nameof(ColumnInfo.IsPrimaryKey)" Title="主键" Width="80" Align="@ColumnAlign.Center"> |
| 114 | + @if (context.IsPrimaryKey) |
| 115 | + { |
| 116 | + <Tag Color="warning">是</Tag> |
| 117 | + } |
| 118 | + else |
| 119 | + { |
| 120 | + <Tag Color="default">否</Tag> |
| 121 | + } |
| 122 | + </AntDesign.Column> |
| 123 | + <AntDesign.Column TData="string" DataIndex="@nameof(ColumnInfo.Description)" Title="描述"> |
| 124 | + @(context.Description ?? "无描述") |
| 125 | + </AntDesign.Column> |
| 126 | + </Table> |
| 127 | + </ChildContent> |
| 128 | + </Card> |
| 129 | + } |
| 130 | + else if (!_loading) |
| 131 | + { |
| 132 | + <Result Status="404" |
| 133 | + Title="表不存在" |
| 134 | + SubTitle="@($"找不到表 '{TableName}' 的信息,可能该表未进行训练。")"> |
| 135 | + <Extra> |
| 136 | + <Button Type="@ButtonType.Primary" OnClick="@NavigateToTableList"> |
| 137 | + 返回表列表 |
| 138 | + </Button> |
| 139 | + <Button OnClick="@NavigateToConnection"> |
| 140 | + 连接详情 |
| 141 | + </Button> |
| 142 | + </Extra> |
| 143 | + </Result> |
| 144 | + } |
| 145 | + </ChildContent> |
| 146 | + </Card> |
| 147 | + </ChildContent> |
| 148 | +</PageContainer> |
| 149 | + |
| 150 | +@code { |
| 151 | + [Parameter] public string ConnectionId { get; set; } = string.Empty; |
| 152 | + [Parameter] public string TableName { get; set; } = string.Empty; |
| 153 | + |
| 154 | + private TableInfo? _tableInfo; |
| 155 | + private bool _loading = false; |
| 156 | + |
| 157 | + protected override async Task OnInitializedAsync() |
| 158 | + { |
| 159 | + await LoadTableData(); |
| 160 | + } |
| 161 | + |
| 162 | + private async Task LoadTableData() |
| 163 | + { |
| 164 | + if (string.IsNullOrEmpty(ConnectionId) || string.IsNullOrEmpty(TableName)) |
| 165 | + { |
| 166 | + await MessageService.Error("连接ID或表名不能为空"); |
| 167 | + NavigateToTableList(); |
| 168 | + return; |
| 169 | + } |
| 170 | + |
| 171 | + _loading = true; |
| 172 | + try |
| 173 | + { |
| 174 | + _tableInfo = await SchemaTrainingService.GetTableDetailAsync(ConnectionId, TableName); |
| 175 | + if (_tableInfo == null) |
| 176 | + { |
| 177 | + await MessageService.Warning($"未找到表 '{TableName}' 的训练信息"); |
| 178 | + } |
| 179 | + } |
| 180 | + catch (Exception ex) |
| 181 | + { |
| 182 | + await MessageService.Error($"加载表详细信息失败: {ex.Message}"); |
| 183 | + } |
| 184 | + finally |
| 185 | + { |
| 186 | + _loading = false; |
| 187 | + StateHasChanged(); |
| 188 | + } |
| 189 | + } |
| 190 | + |
| 191 | + private void NavigateToTableList() |
| 192 | + { |
| 193 | + NavigationManager.NavigateTo($"/database-connection/trained-tables/{ConnectionId}"); |
| 194 | + } |
| 195 | + |
| 196 | + private void NavigateToConnection() |
| 197 | + { |
| 198 | + NavigationManager.NavigateTo($"/database-connection/details/{ConnectionId}"); |
| 199 | + } |
| 200 | + |
| 201 | + private string GetDataTypeColor(string dataType) |
| 202 | + { |
| 203 | + if (string.IsNullOrEmpty(dataType)) |
| 204 | + return ""; |
| 205 | + |
| 206 | + var type = dataType.ToLower(); |
| 207 | + return type switch |
| 208 | + { |
| 209 | + var t when t.Contains("int") || t.Contains("number") || t.Contains("decimal") || t.Contains("numeric") => "blue", |
| 210 | + var t when t.Contains("varchar") || t.Contains("text") || t.Contains("char") || t.Contains("string") => "green", |
| 211 | + var t when t.Contains("datetime") || t.Contains("timestamp") || t.Contains("date") || t.Contains("time") => "orange", |
| 212 | + var t when t.Contains("bool") || t.Contains("bit") => "purple", |
| 213 | + var t when t.Contains("float") || t.Contains("real") || t.Contains("double") => "cyan", |
| 214 | + var t when t.Contains("binary") || t.Contains("blob") || t.Contains("image") => "red", |
| 215 | + _ => "default" |
| 216 | + }; |
| 217 | + } |
| 218 | +} |
0 commit comments