This commit is contained in:
zpc 2025-11-08 00:02:14 +08:00
parent 05ecd67e3b
commit 932eae46ad
46 changed files with 1582 additions and 160 deletions

View File

@ -1,2 +1,2 @@
VUE_APP_BASE=/ #打包路径
# VUE_APP_BASE=/ #打包路径
VITE_API_URL=http://localhost:901/

View File

@ -48,14 +48,7 @@ interface DataItem {
}
const data = reactive([]);
// for (let i = 0; i < 100; i++) {
// data.push({
// key: i,
// name: `Edrward ${i}`,
// age: 32,
// address: `London Park no. ${i}`,
// });
// }
//
const props = defineProps<{ onSuccess: () => void }>();
@ -83,25 +76,6 @@ defineExpose({
_data = ldata;
_key = key;
loadData();
// data.splice(0, data.length);
// state.visible = true;
// T_Products_RewardService.getList(key).then((res) => {
// console.log(res);
// if (res.data != null) {
// res.data.forEach((element) => {
// data.push(element);
// });
// }
// });
// T_Products_RewardService.findList(state.page, state.size, state.search.vm, state.search.sort);
// refForm.value?.resetFields();
// //
// state.loading = true;
// T_Products_RewardService.findForm(key).then((res) => {
// state.loading = false;
// if (res.code != 200) return;
// state.vm = res.data;
// });
},
});
const addReward = () => {

View File

@ -52,6 +52,8 @@ async function findList() {
state.size = result.data.size;
state.total = result.data.total;
state.columns = result.data.columns;
state.data = result.data.dataSource;
}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
using GenerateSeeds;
using System.Text;
var connectionString = "Server=192.168.195.2;Database=MiaoYu;User ID=zpc;Password=zpc;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;";
var connectionString = "Server=192.168.195.15;Database=MiaoYu;User ID=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;";
IFreeSql fsql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.SqlServer, connectionString)

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTCharacterLabelModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Character_Label 种子数据=============================================
modelBuilder.Entity<TCharacterLabel>().HasData(new TCharacterLabel(){Id=1,CreateTime=DateTime.Parse("1990/4/24 6:41:45"),LabelName="二次元",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2016/10/23 13:08:44")},new TCharacterLabel(){Id=2,CreateTime=DateTime.Parse("2011/6/3 8:15:23"),LabelName="美女",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2003/9/12 17:04:38")},new TCharacterLabel(){Id=3,CreateTime=DateTime.Parse("2001/1/17 0:40:56"),LabelName="神秘",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("1975/12/15 10:00:52")},new TCharacterLabel(){Id=4,CreateTime=DateTime.Parse("1973/3/24 2:29:44"),LabelName="女巫",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("1983/11/12 6:03:06")},new TCharacterLabel(){Id=5,CreateTime=DateTime.Parse("2003/7/27 4:52:48"),LabelName="预知未来",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2007/12/17 0:33:37")},new TCharacterLabel(){Id=6,CreateTime=DateTime.Parse("1995/1/5 20:52:21"),LabelName="古代",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2017/3/2 9:28:21")},new TCharacterLabel(){Id=7,CreateTime=DateTime.Parse("1990/11/5 19:24:50"),LabelName="大小姐",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("1995/2/9 13:46:55")},new TCharacterLabel(){Id=8,CreateTime=DateTime.Parse("1974/12/25 17:25:05"),LabelName="善良",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("1977/12/21 22:44:03")},new TCharacterLabel(){Id=9,CreateTime=DateTime.Parse("2002/6/19 12:21:28"),LabelName="聪慧",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("1998/12/13 16:08:18")},new TCharacterLabel(){Id=10,CreateTime=DateTime.Parse("2017/4/14 10:41:49"),LabelName="外星人",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2004/6/6 20:16:03")});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTCharacterLabelRelationModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Character_Label_Relation 种子数据=============================================
modelBuilder.Entity<TCharacterLabelRelation>().HasData(new TCharacterLabelRelation(){Id=1,CharacterId=1,CharacterLabelId=1,CreateTime=DateTime.Parse("2024/1/1 0:00:00"),TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2024/1/1 0:00:00")},new TCharacterLabelRelation(){Id=2,CharacterId=1,CharacterLabelId=2,CreateTime=DateTime.Parse("2024/1/1 0:00:00"),TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2024/1/1 0:00:00")});
}
}

View File

@ -0,0 +1,14 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTCharacterModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Character 种子数据=============================================
modelBuilder.Entity<TCharacter>().HasData(new TCharacter(){Id=1,BgImg=1,Biography="你那商业联姻得来的妻子,原本的天才女孩,聪明伶俐,生的漂亮、端庄,不知贵圈多少人梦寐以求的存在。
?
宿....",CreateTime=DateTime.Parse("2021/1/1 0:00:00"),Gender=1,IconImg=2,ModelConfigId=1,Name="",Prologue=")()",System=null,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2021/1/1 0:00:00"),Visibility=bool.Parse("False")},new TCharacter(){Id=2,BgImg=1,Biography="使",CreateTime=DateTime.Parse("2021/1/1 0:00:00"),Gender=1,IconImg=2,ModelConfigId=1,Name="",Prologue="",System=null,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2021/1/1 0:00:00"),Visibility=bool.Parse("False")},new TCharacter(){Id=3,BgImg=1,Biography="",CreateTime=DateTime.Parse("2021/1/1 0:00:00"),Gender=1,IconImg=2,ModelConfigId=1,Name="",Prologue="",System=null,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2021/1/1 0:00:00"),Visibility=bool.Parse("False")});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTCharacterTypeIntimacyModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Character_Type_Intimacy 种子数据=============================================
modelBuilder.Entity<TCharacterTypeIntimacy>().HasData(new TCharacterTypeIntimacy(){Id=1,CharacterId=1,CreateTime=DateTime.Parse("2024/1/1 0:00:00"),OrderBy=1,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),TypeId=1,UpdateTIme=DateTime.Parse("2024/1/1 0:00:00")});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTCharacterTypeModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Character_Type 种子数据=============================================
modelBuilder.Entity<TCharacterType>().HasData(new TCharacterType(){Id=1,CreateTime=DateTime.Parse("2024/7/14 18:06:31"),IsNotCategoryShow=bool.Parse("False"),Name="虚拟想象",OrderBy=1,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2024/7/14 18:06:35")},new TCharacterType(){Id=2,CreateTime=DateTime.Parse("2024/7/14 18:09:27"),IsNotCategoryShow=bool.Parse("False"),Name="IP同人",OrderBy=2,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2024/7/14 18:09:29")});
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTImageConfigModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Image_Config 种子数据=============================================
modelBuilder.Entity<TImageConfig>().HasData(new TImageConfig(){Id=1,ImageId=1,Name="背景图",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),Url="https://cos.shhuanmeng.com/image/bj.png"},new TImageConfig(){Id=2,ImageId=2,Name="头像",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),Url="https://cos.shhuanmeng.com/image/touxiang.png"});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTModelConfigModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Model_Config 种子数据=============================================
modelBuilder.Entity<TModelConfig>().HasData(new TModelConfig(){Id=1,AnthropicVersion="2023-06-01",ApiKey="sk-V6d51cc6aa28906caecb7f22803d92ae3f18cfeb799nh4mc",CreateTime=DateTime.Parse("2021/1/1 0:00:00"),MaxTokens=1024,Model="claude-3-sonnet-20240229",ModelName="claude3",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateTime=DateTime.Parse("2021/1/1 0:00:00"),Url="https://api.gptsapi.net/v1/messages"});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTUserChatModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_User_Chat 种子数据=============================================
modelBuilder.Entity<TUserChat>().HasData(new TUserChat(){Id=1,CharacterId=1,CreateAt=DateTime.Parse("2024/7/15 18:30:08"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("2d72d7b5-6d8f-4a72-81f5-2eb40797607e"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 14:28:57"),UserId=2},new TUserChat(){Id=2,CharacterId=1,CreateAt=DateTime.Parse("2024/7/16 18:29:37"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("b4e98a18-f095-43de-a16e-24e0902e0478"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/16 18:29:37"),UserId=0},new TUserChat(){Id=3,CharacterId=2,CreateAt=DateTime.Parse("2024/7/17 14:57:51"),IsDelete=bool.Parse("True"),ModelConfigId=1,SessionId=Guid.Parse("49a8c5a7-1c4f-4b7f-adb4-d834873d82ef"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 15:12:42"),UserId=3},new TUserChat(){Id=4,CharacterId=3,CreateAt=DateTime.Parse("2024/7/17 15:01:49"),IsDelete=bool.Parse("True"),ModelConfigId=1,SessionId=Guid.Parse("8fe3f1a9-a437-4d01-ae6e-0bd9c5a8bd65"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 15:28:13"),UserId=3},new TUserChat(){Id=5,CharacterId=1,CreateAt=DateTime.Parse("2024/7/17 15:31:56"),IsDelete=bool.Parse("True"),ModelConfigId=1,SessionId=Guid.Parse("d91c0bb8-7af9-4dfb-a435-065f7d63d3a5"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 16:08:47"),UserId=3},new TUserChat(){Id=6,CharacterId=3,CreateAt=DateTime.Parse("2024/7/17 15:34:45"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("b3531adb-d937-486d-b35b-8e90d988831a"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 15:53:48"),UserId=2},new TUserChat(){Id=7,CharacterId=3,CreateAt=DateTime.Parse("2024/7/17 16:06:56"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("7f02d66a-47f5-4043-a8d2-f23d3d473427"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 19:50:32"),UserId=3},new TUserChat(){Id=8,CharacterId=2,CreateAt=DateTime.Parse("2024/7/17 16:08:01"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("30903563-b410-4133-9369-fd67848f3822"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 16:08:01"),UserId=3},new TUserChat(){Id=9,CharacterId=1,CreateAt=DateTime.Parse("2024/7/17 16:08:53"),IsDelete=bool.Parse("True"),ModelConfigId=1,SessionId=Guid.Parse("5cfbe41d-8e29-4787-951b-be57465a27f2"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 16:09:14"),UserId=3},new TUserChat(){Id=10,CharacterId=1,CreateAt=DateTime.Parse("2024/7/17 16:09:19"),IsDelete=bool.Parse("False"),ModelConfigId=1,SessionId=Guid.Parse("9c839ba0-2c09-44cd-8ab7-8bdd39e28b65"),SessionName="新会话",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdateAt=DateTime.Parse("2024/7/17 16:09:19"),UserId=3});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTUserDataModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_User_Data 种子数据=============================================
modelBuilder.Entity<TUserData>().HasData(new TUserData(){Id=2,UserId=2,CreatedAt =DateTime.Parse("2024/7/9 3:41:00"),Currency=0,NickName="新用户",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/9 3:41:00"),UserIconUrl="",VipType=0},new TUserData(){Id=3,UserId=3,CreatedAt =DateTime.Parse("2024/7/10 21:52:49"),Currency=0,NickName="新用户",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/10 21:52:49"),UserIconUrl="",VipType=0});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTUserModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_User 种子数据=============================================
modelBuilder.Entity<TUser>().HasData(new TUser(){Id=1,CreatedAt=DateTime.Parse("2024/7/9 3:33:09"),Email="",Ip=null,IsActive=bool.Parse("True"),LastLoginAt=DateTime.Parse("2024/7/9 3:33:09"),LastLoginTypeAt=1,NickName="新用户",PhoneNum="18761127117",RegisterType=1,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/9 3:33:09"),UserName="18761127117"},new TUser(){Id=2,CreatedAt=DateTime.Parse("2024/7/9 3:40:58"),Email="",Ip="::ffff:101.229.91.116",IsActive=bool.Parse("True"),LastLoginAt=DateTime.Parse("2024/7/17 12:55:01"),LastLoginTypeAt=1,NickName="新用户",PhoneNum="17521010998",RegisterType=1,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/9 3:40:58"),UserName="17521010998"},new TUser(){Id=3,CreatedAt=DateTime.Parse("2024/7/10 21:52:49"),Email="",Ip="::ffff:101.229.91.116",IsActive=bool.Parse("True"),LastLoginAt=DateTime.Parse("2024/7/18 0:11:31"),LastLoginTypeAt=0,NickName="新用户",PhoneNum="18631081161",RegisterType=1,TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/10 21:52:49"),UserName="18631081161"});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTUserPhoneAccountModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_User_Phone_Account 种子数据=============================================
modelBuilder.Entity<TUserPhoneAccount>().HasData(new TUserPhoneAccount(){Id=2,CreatedAt=DateTime.Parse("2024/7/9 3:41:03"),LastLoginAt=DateTime.Parse("2024/7/9 3:41:03"),NikeName="新用户",PhoneNum="17521010998",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/9 3:41:03"),UserId=2,VerificationCode="347544"},new TUserPhoneAccount(){Id=3,CreatedAt=DateTime.Parse("2024/7/10 21:52:49"),LastLoginAt=DateTime.Parse("2024/7/10 21:52:49"),NikeName="新用户",PhoneNum="18631081161",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),UpdatedAt=DateTime.Parse("2024/7/10 21:52:49"),UserId=3,VerificationCode="820042"});
}
}

View File

@ -0,0 +1,12 @@
namespace MiaoYu.Repository.EntityFramework.Admin.Migrations.SeedsDatas.Datas;
public static class MigrationsTVerificationCodeModelBuilderExtensions
{
public static void Seed(this ModelBuilder modelBuilder)
{
// ===============================================表T_Verification_Code 种子数据=============================================
modelBuilder.Entity<TVerificationCode>().HasData(new TVerificationCode(){Id=1,Code="959746",CreateAt=DateTime.Parse("2024/7/8 23:37:27"),CreateDay=20240708,ExpireAt=DateTime.Parse("2024/7/8 23:41:14"),Key="18761127117",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=2,Code="327537",CreateAt=DateTime.Parse("2024/7/9 3:32:26"),CreateDay=20240709,ExpireAt=DateTime.Parse("2024/7/9 3:37:24"),Key="18761127117",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=3,Code="347544",CreateAt=DateTime.Parse("2024/7/9 3:40:27"),CreateDay=20240709,ExpireAt=DateTime.Parse("2024/7/9 3:45:26"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=4,Code="295455",CreateAt=DateTime.Parse("2024/7/9 23:17:11"),CreateDay=20240709,ExpireAt=DateTime.Parse("2024/7/9 23:22:10"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=5,Code="136582",CreateAt=DateTime.Parse("2024/7/9 23:55:10"),CreateDay=20240709,ExpireAt=DateTime.Parse("2024/7/9 23:59:51"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=6,Code="148088",CreateAt=DateTime.Parse("2024/7/10 18:21:23"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 18:26:22"),Key="18631081160",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=7,Code="407608",CreateAt=DateTime.Parse("2024/7/10 18:22:32"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 18:27:32"),Key="18631081160",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=8,Code="845877",CreateAt=DateTime.Parse("2024/7/10 18:24:29"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 18:29:29"),Key="18631081160",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=9,Code="761664",CreateAt=DateTime.Parse("2024/7/10 18:26:13"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 18:31:13"),Key="18631081160",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=10,Code="570114",CreateAt=DateTime.Parse("2024/7/10 18:28:09"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 18:33:08"),Key="18631081160",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=11,Code="886514",CreateAt=DateTime.Parse("2024/7/10 20:55:15"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 21:00:14"),Key="18631081161",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=12,Code="820042",CreateAt=DateTime.Parse("2024/7/10 21:52:33"),CreateDay=20240710,ExpireAt=DateTime.Parse("2024/7/10 21:57:32"),Key="18631081161",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=13,Code="344030",CreateAt=DateTime.Parse("2024/7/11 16:14:58"),CreateDay=20240711,ExpireAt=DateTime.Parse("2024/7/11 16:19:57"),Key="18631081161",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=14,Code="663122",CreateAt=DateTime.Parse("2024/7/14 23:01:45"),CreateDay=20240714,ExpireAt=DateTime.Parse("2024/7/14 23:06:44"),Key="18631081161",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=15,Code="875704",CreateAt=DateTime.Parse("2024/7/15 18:28:43"),CreateDay=20240715,ExpireAt=DateTime.Parse("2024/7/15 18:33:38"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=16,Code="565779",CreateAt=DateTime.Parse("2024/7/16 18:46:32"),CreateDay=20240716,ExpireAt=DateTime.Parse("2024/7/16 18:51:32"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0},new TVerificationCode(){Id=17,Code="523837",CreateAt=DateTime.Parse("2024/7/17 12:54:43"),CreateDay=20240717,ExpireAt=DateTime.Parse("2024/7/17 12:59:42"),Key="17521010998",Remarks="登录验证码",TenantId=Guid.Parse("00000000-0000-0000-0000-000000000000"),VerificationType=0});
}
}

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33402.96
# Visual Studio Version 18
VisualStudioVersion = 18.0.11201.2 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00 Core", "00 Core", "{DB46F54A-9F53-44EC-80F8-9E53F0B871CF}"
EndProject
@ -54,6 +54,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiaoYu.Core.Cos", "MiaoYu.Core.Cos\MiaoYu.Core.Cos.csproj", "{3FBBDE5E-2D2C-428B-A2BF-298499ABA5A7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiaoYu.Repository.LiveForum.Admin", "MiaoYu.Repository.LiveForum.Admin\MiaoYu.Repository.LiveForum.Admin.csproj", "{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -132,6 +134,10 @@ Global
{3FBBDE5E-2D2C-428B-A2BF-298499ABA5A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3FBBDE5E-2D2C-428B-A2BF-298499ABA5A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3FBBDE5E-2D2C-428B-A2BF-298499ABA5A7}.Release|Any CPU.Build.0 = Release|Any CPU
{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -155,6 +161,7 @@ Global
{925EF035-4A41-42E4-A3A4-B8E9AE52F6B7} = {DC7A7E4A-B4DC-4958-BAA5-2BBB1A153B5F}
{39C765DB-41E7-4BC6-B75E-2A90CFF3A8EF} = {451BE0BB-26ED-47ED-ABC7-23001D21410C}
{3FBBDE5E-2D2C-428B-A2BF-298499ABA5A7} = {DB46F54A-9F53-44EC-80F8-9E53F0B871CF}
{2AF20E5B-478F-46FE-8F8C-A385BB5D5EC7} = {451BE0BB-26ED-47ED-ABC7-23001D21410C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E3C61955-46C1-4D06-994F-C86A72B2B0E2}

View File

@ -1,4 +1,7 @@
using MiaoYu.Core.Cos;
using MiaoYu.Repository.LiveForum.Admin;
using TencentCloud.Cme.V20191029.Models;
namespace MiaoYu.Api.Admin;
@ -12,6 +15,7 @@ namespace MiaoYu.Api.Admin;
CoreIdentityStartup,
AdminRepositoryStartup,
ChatAdminRepositoryStartup,
LiveForumAdminRepositoryStartup,
CoreSwaggerJwtStartup,
SharedAdminStartup,
CoreCosStartup>]

View File

@ -0,0 +1,68 @@
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
/// <summary>
/// 数据源配置
/// </summary>
public class DataSourceConfig
{
/// <summary>
/// 数据库标识Admin, MiaoYuChat, LiveForum
/// </summary>
public string DatabaseKey { get; set; } = string.Empty;
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; } = string.Empty;
/// <summary>
/// 实体项目命名空间
/// </summary>
public string EntityNamespace { get; set; } = string.Empty;
/// <summary>
/// 实体类路径模板(支持占位符:{RootPath}, {Namespace}, {EntityName}, {EntityNamePlural}, {TableName}
/// </summary>
public string ModelPathTemplate { get; set; } = string.Empty;
/// <summary>
/// 服务层路径模板
/// </summary>
public string ServicePathTemplate { get; set; } = string.Empty;
/// <summary>
/// 控制器路径模板
/// </summary>
public string ControllerPathTemplate { get; set; } = string.Empty;
/// <summary>
/// 前端Index页面路径模板
/// </summary>
public string ClientIndexPathTemplate { get; set; } = string.Empty;
/// <summary>
/// 前端Info页面路径模板
/// </summary>
public string ClientInfoPathTemplate { get; set; } = string.Empty;
/// <summary>
/// 前端Service路径模板
/// </summary>
public string ClientServicePathTemplate { get; set; } = string.Empty;
/// <summary>
/// 代码生成模板目录
/// </summary>
public string TemplatePath { get; set; } = string.Empty;
/// <summary>
/// 实体类命名规则(保持原名 or 驼峰转换)
/// </summary>
public EntityNamingStrategy NamingStrategy { get; set; }
/// <summary>
/// 排序权重(数字越小越靠前)
/// </summary>
public int Order { get; set; }
}

View File

@ -0,0 +1,23 @@
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
/// <summary>
/// 数据源常量
/// </summary>
public static class DataSourceConstants
{
/// <summary>
/// 后台管理系统数据库
/// </summary>
public const string Admin = "Admin";
/// <summary>
/// 喵语AI聊天数据库
/// </summary>
public const string MiaoYuChat = "MiaoYuChat";
/// <summary>
/// 直播论坛数据库(预留)
/// </summary>
public const string LiveForum = "LiveForum";
}

View File

@ -0,0 +1,18 @@
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
/// <summary>
/// 实体命名策略
/// </summary>
public enum EntityNamingStrategy
{
/// <summary>
/// 保持数据库表名原样
/// </summary>
KeepOriginal = 0,
/// <summary>
/// 转换为驼峰命名(去除前缀下划线)
/// </summary>
ToPascalCase = 1
}

View File

@ -0,0 +1,25 @@
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
/// <summary>
/// 数据源提供者接口
/// </summary>
public interface IDataSourceProvider
{
/// <summary>
/// 数据源配置
/// </summary>
DataSourceConfig Config { get; }
/// <summary>
/// 获取该数据源的所有表信息
/// </summary>
/// <returns>表信息列表</returns>
List<DbTableInfo> GetTables();
/// <summary>
/// 获取DbContext用于获取FreeSql实例
/// </summary>
/// <returns>数据库上下文</returns>
DbContext GetDbContext();
}

View File

@ -0,0 +1,44 @@
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
/// <summary>
/// 数据源扩展方法
/// </summary>
public static class DataSourceExtensions
{
/// <summary>
/// 从 Schema 中提取数据库标识
/// </summary>
/// <param name="schema">Schema字符串</param>
/// <returns>数据库标识</returns>
public static string ExtractDatabaseKey(this string schema)
{
if (string.IsNullOrWhiteSpace(schema))
return DataSourceConstants.Admin;
if (schema.Contains("."))
{
var parts = schema.Split('.');
return parts.Length > 1 ? parts[1] : DataSourceConstants.Admin;
}
return DataSourceConstants.Admin;
}
/// <summary>
/// 清理 Schema移除数据库标识
/// </summary>
/// <param name="schema">Schema字符串</param>
/// <returns>清理后的Schema</returns>
public static string CleanSchema(this string schema)
{
if (string.IsNullOrWhiteSpace(schema))
return schema;
return schema.Contains(".")
? schema.Split('.')[0]
: schema;
}
}

View File

@ -0,0 +1,70 @@
using HZY.Framework.DependencyInjection.Attributes;
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
/// <summary>
/// 数据源管理器
/// </summary>
[Component]
public class DataSourceManager : IScopedDependency
{
private readonly IEnumerable<IDataSourceProvider> _providers;
/// <summary>
/// 构造函数通过依赖注入自动收集所有IDataSourceProvider实现
/// </summary>
/// <param name="providers">所有数据源提供者</param>
public DataSourceManager(IEnumerable<IDataSourceProvider> providers)
{
_providers = providers.OrderBy(p => p.Config.Order);
}
/// <summary>
/// 获取所有数据源提供者
/// </summary>
/// <returns>数据源提供者集合</returns>
public IEnumerable<IDataSourceProvider> GetAllProviders() => _providers;
/// <summary>
/// 根据数据库标识获取数据源提供者
/// </summary>
/// <param name="databaseKey">数据库标识Admin, MiaoYuChat</param>
/// <returns>数据源提供者如果未找到返回null</returns>
public IDataSourceProvider? GetProvider(string databaseKey)
{
if (string.IsNullOrWhiteSpace(databaseKey))
return null;
return _providers.FirstOrDefault(p =>
p.Config.DatabaseKey.Equals(databaseKey, StringComparison.OrdinalIgnoreCase));
}
/// <summary>
/// 获取所有数据源的表信息
/// </summary>
/// <returns>所有表信息列表</returns>
public List<DbTableInfo> GetAllTables()
{
var allTables = new List<DbTableInfo>();
foreach (var provider in _providers)
{
try
{
var tables = provider.GetTables();
if (tables != null && tables.Count > 0)
{
allTables.AddRange(tables);
}
}
catch (Exception ex)
{
LogUtil.Log.Warning($"获取数据源 {provider.Config.DatabaseKey} 的表信息失败: {ex.Message}");
}
}
return allTables;
}
}

View File

@ -0,0 +1,58 @@
using HZY.Framework.DependencyInjection.Attributes;
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
/// <summary>
/// 路径解析器
/// </summary>
[Component]
public class PathResolver : IScopedDependency
{
private readonly IWebHostEnvironment _environment;
public PathResolver(IWebHostEnvironment environment)
{
_environment = environment;
}
/// <summary>
/// 解析路径模板
/// </summary>
/// <param name="template">路径模板(支持占位符)</param>
/// <param name="config">数据源配置</param>
/// <param name="tableName">表名</param>
/// <returns>解析后的完整路径</returns>
public string ResolvePath(string template, DataSourceConfig config, string tableName)
{
if (string.IsNullOrWhiteSpace(template))
return string.Empty;
var rootPath = _environment.ContentRootPath
.Replace("\\" + _environment.ApplicationName, "");
var entityName = GetEntityName(tableName, config.NamingStrategy);
return template
.Replace("{RootPath}", rootPath)
.Replace("{AppPath}", _environment.ContentRootPath)
.Replace("{Namespace}", config.EntityNamespace)
.Replace("{EntityName}", entityName)
.Replace("{EntityNamePlural}", entityName + "s")
.Replace("{TableName}", tableName);
}
/// <summary>
/// 根据命名策略获取实体名
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="strategy">命名策略</param>
/// <returns>实体名</returns>
private string GetEntityName(string tableName, EntityNamingStrategy strategy)
{
return strategy == EntityNamingStrategy.ToPascalCase
? tableName.ToLineConvertHump()
: tableName;
}
}

View File

@ -1,3 +1,6 @@
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
/// <summary>
@ -24,20 +27,28 @@ public class CodeGenerationService : ICodeGenerationService
private readonly IDatabaseTableService _databaseTableService;
private readonly IRazorViewRender _razorViewRender;
private readonly DataSourceManager _dataSourceManager;
private readonly PathResolver _pathResolver;
/// <summary>
///
/// 构造函数
/// </summary>
/// <param name="databaseTableService"></param>
/// <param name="razorViewRender"></param>
/// <param name="webHostEnvironment"></param>
/// <param name="databaseTableService">数据库表服务</param>
/// <param name="razorViewRender">Razor视图渲染器</param>
/// <param name="webHostEnvironment">Web宿主环境</param>
/// <param name="dataSourceManager">数据源管理器</param>
/// <param name="pathResolver">路径解析器</param>
public CodeGenerationService(IDatabaseTableService databaseTableService,
IRazorViewRender razorViewRender,
IWebHostEnvironment webHostEnvironment)
IWebHostEnvironment webHostEnvironment,
DataSourceManager dataSourceManager,
PathResolver pathResolver)
{
_databaseTableService = databaseTableService;
_razorViewRender = razorViewRender;
_webRootPath = webHostEnvironment.WebRootPath;
_dataSourceManager = dataSourceManager;
_pathResolver = pathResolver;
}
/// <summary>
@ -88,50 +99,55 @@ public class CodeGenerationService : ICodeGenerationService
}
/// <summary>
/// 根据 lowCodeTable 填充路径
/// 根据 lowCodeTable 填充路径(支持多数据源)
/// </summary>
/// <returns></returns>
/// <param name="lowCodeTable">低代码表配置</param>
/// <returns>填充路径后的低代码表配置</returns>
public LowCodeTable FillPathByLowCodeTable(LowCodeTable lowCodeTable)
{
var provider = _dataSourceManager.GetProvider(lowCodeTable.DataBase ?? DataSourceConstants.Admin);
if (provider == null)
{
LogUtil.Log.Warning($"未找到数据源 {lowCodeTable.DataBase}使用默认Admin配置");
provider = _dataSourceManager.GetProvider(DataSourceConstants.Admin);
}
var rootPath = App.WebApplication.Environment.ContentRootPath.Replace("\\" + App.WebApplication.Environment.ApplicationName, "");
var config = provider!.Config;
if (string.IsNullOrWhiteSpace(lowCodeTable.ModelPath))
{
if (lowCodeTable.DataBase == "MiaoYuChat")
{
lowCodeTable.ModelPath = rootPath + $"\\{typeof(ChatAdminRepositoryStartup).Namespace}\\Entities\\Apps";
}
else
{
lowCodeTable.ModelPath = rootPath + $"\\{typeof(AdminRepositoryStartup).Namespace}\\Entities\\Apps";
}
lowCodeTable.ModelPath = _pathResolver.ResolvePath(
config.ModelPathTemplate, config, lowCodeTable.TableName);
}
if (string.IsNullOrWhiteSpace(lowCodeTable.ServicePath))
{
lowCodeTable.ServicePath = App.WebApplication.Environment.ContentRootPath + "\\ApplicationServices\\Apps";
lowCodeTable.ServicePath = _pathResolver.ResolvePath(
config.ServicePathTemplate, config, lowCodeTable.TableName);
}
if (string.IsNullOrWhiteSpace(lowCodeTable.ControllerPath))
{
lowCodeTable.ControllerPath = App.WebApplication.Environment.ContentRootPath + "\\Controllers\\Apps";
lowCodeTable.ControllerPath = _pathResolver.ResolvePath(
config.ControllerPathTemplate, config, lowCodeTable.TableName);
}
rootPath = rootPath.Substring(0, rootPath.LastIndexOf("\\"));
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientIndexPath))
{
lowCodeTable.ClientIndexPath = rootPath + "\\" + projectClientName + "\\src\\views\\apps";
lowCodeTable.ClientIndexPath = _pathResolver.ResolvePath(
config.ClientIndexPathTemplate, config, lowCodeTable.TableName);
}
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientInfoPath))
{
lowCodeTable.ClientInfoPath = rootPath + "\\" + projectClientName + "\\src\\views\\apps";
lowCodeTable.ClientInfoPath = _pathResolver.ResolvePath(
config.ClientInfoPathTemplate, config, lowCodeTable.TableName);
}
if (string.IsNullOrWhiteSpace(lowCodeTable.ClientServicePath))
{
lowCodeTable.ClientServicePath = rootPath + "\\" + projectClientName + "\\src\\services\\apps";
lowCodeTable.ClientServicePath = _pathResolver.ResolvePath(
config.ClientServicePathTemplate, config, lowCodeTable.TableName);
}
return lowCodeTable;
@ -154,99 +170,81 @@ public class CodeGenerationService : ICodeGenerationService
}
/// <summary>
/// 生成model
/// 生成model(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenModelAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateModel, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateModel, context));
}
/// <summary>
/// 生成service
/// 生成service(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenServiceAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateService, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateService, context));
}
/// <summary>
/// 生成controller
/// 生成controller(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenControllerAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateController, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateController, context));
}
/// <summary>
/// 生成service js
/// 生成service js(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenServiceJsAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateServiceJs, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateServiceJs, context));
}
/// <summary>
/// 生成 index vue
/// 生成 index vue(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenIndexAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateIndex, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateIndex, context));
}
/// <summary>
/// 生成 info vue
/// 生成 info vue(支持多数据源)
/// </summary>
/// <param name="genFormDto"></param>
/// <returns></returns>
public async Task<string> GenInfoAsync(GenFormDto genFormDto)
{
var context = GetGenContextDto(genFormDto);
var _templateRootPath = templateRootPath;
if (context.DataBase == "MiaoYuChat")
{
_templateRootPath = templateRootPath_v4;
}
return ClearSymbol(await _razorViewRender.RenderAsync(_templateRootPath + templateInfo, context));
var provider = _dataSourceManager.GetProvider(context.DataBase ?? DataSourceConstants.Admin);
var templatePath = provider?.Config.TemplatePath ?? templateRootPath;
return ClearSymbol(await _razorViewRender.RenderAsync(templatePath + templateInfo, context));
}

View File

@ -1,3 +1,4 @@
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
using MiaoYu.Repository.ChatAI.Admin.Entities;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl;
@ -15,39 +16,38 @@ public class DatabaseTableService : IDatabaseTableService
private readonly IRepository<LowCodeTableInfo> _lowCodeTableInfoRepository;
private readonly IRepository<T_Image_Config> _imageConfig;
private readonly DataSourceManager _dataSourceManager;
/// <summary>
///
/// 构造函数
/// </summary>
/// <param name="memoryCache"></param>
/// <param name="lowCodeTableRepository"></param>
/// <param name="lowCodeTableInfoRepository"></param>
/// <param name="memoryCache">内存缓存</param>
/// <param name="lowCodeTableRepository">低代码表仓储</param>
/// <param name="lowCodeTableInfoRepository">低代码表字段仓储</param>
/// <param name="imageConfig">图片配置仓储</param>
/// <param name="dataSourceManager">数据源管理器</param>
public DatabaseTableService(
IMemoryCache memoryCache,
IRepository<LowCodeTable> lowCodeTableRepository,
IRepository<LowCodeTableInfo> lowCodeTableInfoRepository,
IRepository<T_Image_Config> imageConfig
IRepository<T_Image_Config> imageConfig,
DataSourceManager dataSourceManager
)
{
_memoryCache = memoryCache;
_lowCodeTableRepository = lowCodeTableRepository;
_lowCodeTableInfoRepository = lowCodeTableInfoRepository;
_imageConfig = imageConfig;
_dataSourceManager = dataSourceManager;
}
/// <summary>
/// 获取所有的表 包含表下面的列
/// 获取所有的表 包含表下面的列(支持多数据源)
/// </summary>
/// <returns></returns>
/// <returns>所有表信息列表</returns>
public virtual List<DbTableInfo> GetAllTableInfos()
{
var list = _lowCodeTableRepository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
var tlist = _imageConfig.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
tlist.ForEach(t =>
{
t.Schema = t.Schema + "." + "MiaoYuChat";
});
list.AddRange(tlist);
return list;
return _dataSourceManager.GetAllTables();
}
/// <summary>

View File

@ -1,3 +1,4 @@
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core;
using MiaoYu.Repository.Admin.Entities.LowCode;
using MiaoYu.Repository.ChatAI.Admin.Entities;
@ -12,18 +13,21 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
private readonly LowCodeTableInfoService _lowCodeTableInfoService;
private readonly IDatabaseTableService _databaseTableService;
private readonly ICodeGenerationService _codeGenerationService;
private readonly DataSourceManager _dataSourceManager;
public LowCodeTableService(
IRepository<LowCodeTable> defaultRepository,
LowCodeTableInfoService lowCodeTableInfoService,
IRepository<LowCodeTableInfo> lowCodeTableInfoRepository,
IDatabaseTableService databaseTableService,
ICodeGenerationService codeGenerationService) : base(defaultRepository)
ICodeGenerationService codeGenerationService,
DataSourceManager dataSourceManager) : base(defaultRepository)
{
_lowCodeTableInfoService = lowCodeTableInfoService;
_lowCodeTableInfoRepository = lowCodeTableInfoRepository;
_databaseTableService = databaseTableService;
_codeGenerationService = codeGenerationService;
_dataSourceManager = dataSourceManager;
}
/// <summary>
@ -85,52 +89,51 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
}
/// <summary>
/// 同步表
/// 同步表(支持多数据源)
/// </summary>
public async Task SynchronizationAsync()
{
var allTables = _databaseTableService.GetAllTableInfos();
var oldAllTables = await _defaultRepository.ToListAllAsync();
#region
var insertList = new List<LowCodeTable>();
var updateList = new List<LowCodeTable>();
var ids = new List<Guid>();
foreach (var item in allTables)
{
var table = oldAllTables.Find(w => w.TableName == item.Name);
var id = Guid.NewGuid();
// 使用扩展方法提取数据库标识
var databaseKey = item.Schema.ExtractDatabaseKey();
var provider = _dataSourceManager.GetProvider(databaseKey);
if (table == null)
{
var lowCodeTable = new LowCodeTable
{
Id = id,
DisplayName = item.Comment,
TableName = item.Name,
EntityName = item.Name.ToLineConvertHump()
DataBase = databaseKey,
Schema = item.Schema.CleanSchema(),
// 根据命名策略生成实体名
EntityName = provider?.Config.NamingStrategy == Abstractions.EntityNamingStrategy.KeepOriginal
? item.Name
: item.Name.ToLineConvertHump()
};
if (item.Schema.Contains(".MiaoYuChat"))
{
item.Schema = item.Schema.Replace(".MiaoYuChat", "");
lowCodeTable.Schema = item.Schema;
lowCodeTable.DataBase = "MiaoYuChat";
lowCodeTable.EntityName = item.Name;
}
insertList.Add(lowCodeTable);
}
else
{
id = table.Id;
if (item.Schema.Contains(".MiaoYuChat"))
{
item.Schema = item.Schema.Replace(".MiaoYuChat", "");
table.Schema = item.Schema;
table.DataBase = "MiaoYuChat";
table.EntityName = item.Name;
}
table.DataBase = databaseKey;
table.Schema = item.Schema.CleanSchema();
table.EntityName = provider?.Config.NamingStrategy == Abstractions.EntityNamingStrategy.KeepOriginal
? item.Name
: item.Name.ToLineConvertHump();
updateList.Add(table);
}
@ -154,8 +157,6 @@ public class LowCodeTableService : ApplicationService<IRepository<LowCodeTable>>
}
_databaseTableService.ClearAllTablesByCache();
#endregion
}
/// <summary>

View File

@ -0,0 +1,42 @@
using HZY.Framework.DependencyInjection.Attributes;
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers;
/// <summary>
/// Admin 数据源提供者
/// </summary>
[Component]
public class AdminDataSourceProvider : IDataSourceProvider, IScopedDependency
{
private readonly IRepository<LowCodeTable> _repository;
public AdminDataSourceProvider(IRepository<LowCodeTable> repository)
{
_repository = repository;
}
public DataSourceConfig Config => new DataSourceConfig
{
DatabaseKey = DataSourceConstants.Admin,
DisplayName = "后台管理系统",
EntityNamespace = typeof(AdminRepositoryStartup).Namespace!,
ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\Apps\\{EntityNamePlural}",
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/",
NamingStrategy = EntityNamingStrategy.ToPascalCase,
Order = 1
};
public List<DbTableInfo> GetTables()
{
return _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
}
public DbContext GetDbContext() => _repository.GetContext()!;
}

View File

@ -0,0 +1,46 @@
using HZY.Framework.DependencyInjection.Attributes;
using MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions;
using MiaoYu.Repository.ChatAI.Admin.Entities;
namespace MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers;
/// <summary>
/// MiaoYuChat 数据源提供者
/// </summary>
[Component]
public class MiaoYuChatDataSourceProvider : IDataSourceProvider, IScopedDependency
{
private readonly IRepository<T_Image_Config> _repository;
public MiaoYuChatDataSourceProvider(IRepository<T_Image_Config> repository)
{
_repository = repository;
}
public DataSourceConfig Config => new DataSourceConfig
{
DatabaseKey = DataSourceConstants.MiaoYuChat,
DisplayName = "喵语AI聊天",
EntityNamespace = typeof(ChatAdminRepositoryStartup).Namespace!,
ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\Apps",
ServicePathTemplate = "{AppPath}\\ApplicationServices\\Apps\\MiaoYuChat",
ControllerPathTemplate = "{AppPath}\\Controllers\\Apps\\MiaoYuChat",
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/templatev4/",
NamingStrategy = EntityNamingStrategy.KeepOriginal,
Order = 2
};
public List<DbTableInfo> GetTables()
{
var tables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
// 标记数据源来源
tables.ForEach(t => t.Schema = t.Schema + "." + Config.DatabaseKey);
return tables;
}
public DbContext GetDbContext() => _repository.GetContext()!;
}

View File

@ -0,0 +1,177 @@
# 低代码平台数据源抽象架构说明
## 概述
低代码平台已重构为基于数据源提供者Provider模式的可扩展架构支持多数据源、配置驱动的代码生成。
## 核心架构
### 1. 抽象层 (Abstractions)
#### IDataSourceProvider
数据源提供者接口,定义了所有数据源必须实现的功能:
- `Config`: 数据源配置信息
- `GetTables()`: 获取数据库表信息
- `GetDbContext()`: 获取数据库上下文
#### DataSourceConfig
数据源配置模型,包含:
- **DatabaseKey**: 数据库标识Admin, MiaoYuChat, LiveForum
- **路径模板**: 支持占位符的路径配置
- `{RootPath}`: 项目根路径
- `{AppPath}`: 应用路径
- `{Namespace}`: 实体命名空间
- `{EntityName}`: 实体名称
- `{EntityNamePlural}`: 实体名称复数形式
- `{TableName}`: 表名
- **TemplatePath**: 代码生成模板目录
- **NamingStrategy**: 实体命名策略(保持原名/驼峰转换)
#### EntityNamingStrategy
命名策略枚举:
- `KeepOriginal`: 保持数据库表名原样
- `ToPascalCase`: 转换为驼峰命名(去除下划线前缀)
### 2. 核心工具 (Core)
#### DataSourceManager
数据源管理器,负责:
- 自动收集所有注册的 `IDataSourceProvider`
- 根据DatabaseKey获取对应的Provider
- 聚合所有数据源的表信息
#### PathResolver
路径解析器,负责:
- 解析路径模板中的占位符
- 应用命名策略转换
- 生成最终的文件路径
#### DataSourceExtensions
扩展方法集,提供:
- `ExtractDatabaseKey()`: 从Schema中提取数据库标识
- `CleanSchema()`: 清理Schema中的数据库标识
### 3. 数据源实现 (Providers)
#### AdminDataSourceProvider
后台管理系统数据源:
- DatabaseKey: `Admin`
- NamingStrategy: `ToPascalCase`(驼峰转换)
- 模板路径: `/wwwroot/code_generation/template/`
- 实体目录: 按复数形式分类(如 `Entities\\Apps\\Users`
#### MiaoYuChatDataSourceProvider
喵语AI聊天数据源
- DatabaseKey: `MiaoYuChat`
- NamingStrategy: `KeepOriginal`(保持原名)
- 模板路径: `/wwwroot/code_generation/templatev4/`
- 实体目录: 扁平结构(如 `Entities\\Apps`
## 新增数据源步骤
### 1. 创建Provider实现
`Providers` 目录下创建新的Provider类
```csharp
public class NewDataSourceProvider : IDataSourceProvider, IScopedDependency
{
private readonly IRepository<YourEntity> _repository;
public NewDataSourceProvider(IRepository<YourEntity> repository)
{
_repository = repository;
}
public DataSourceConfig Config => new DataSourceConfig
{
DatabaseKey = DataSourceConstants.YourDatabase,
DisplayName = "数据库显示名称",
EntityNamespace = typeof(YourRepositoryStartup).Namespace!,
ModelPathTemplate = "{RootPath}\\{Namespace}\\Entities\\YourPath",
ServicePathTemplate = "{AppPath}\\ApplicationServices\\YourPath",
ControllerPathTemplate = "{AppPath}\\Controllers\\YourPath",
ClientIndexPathTemplate = "{RootPath}\\admin-client\\src\\views\\YourPath",
ClientInfoPathTemplate = "{RootPath}\\admin-client\\src\\views\\YourPath",
ClientServicePathTemplate = "{RootPath}\\admin-client\\src\\services\\YourPath",
TemplatePath = "/wwwroot/code_generation/template/",
NamingStrategy = EntityNamingStrategy.ToPascalCase,
Order = 3
};
public List<DbTableInfo> GetTables()
{
var tables = _repository.UnitOfWork.FreeSqlOrm.DbFirst.GetTablesByDatabase();
// 标记数据源来源
tables.ForEach(t => t.Schema = t.Schema + "." + Config.DatabaseKey);
return tables;
}
public DbContext GetDbContext() => _repository.GetContext()!;
}
```
### 2. 添加常量定义
`DataSourceConstants` 中添加新的数据库标识:
```csharp
public const string YourDatabase = "YourDatabase";
```
### 3. 自动注册
由于Provider类实现了 `IScopedDependency`,依赖注入系统会自动注册。
`DataSourceManager` 会在构造函数中自动收集所有Provider实例。
### 4. 验证
启动项目后:
1. 表同步功能会自动识别新数据源
2. 代码生成会根据新配置生成相应代码
3. 无需修改任何业务逻辑代码
## 关键服务说明
### DatabaseTableService
- `GetAllTableInfos()`: 获取所有数据源的表信息通过DataSourceManager聚合
### CodeGenerationService
- `FillPathByLowCodeTable()`: 根据数据源配置填充路径
- `GenModelAsync()`: 根据数据源模板生成Model代码
- `GenServiceAsync()`: 生成Service代码
- `GenControllerAsync()`: 生成Controller代码
- `GenIndexAsync()`: 生成前端Index页面
- `GenInfoAsync()`: 生成前端Info页面
- `GenServiceJsAsync()`: 生成前端Service代码
### LowCodeTableService
- `SynchronizationAsync()`: 同步所有数据源的表到低代码系统
- 自动识别数据源
- 应用相应的命名策略
- 保存数据库标识和Schema信息
## 优势
1. **开放封闭原则**: 新增数据源无需修改现有代码只需添加Provider
2. **配置驱动**: 所有路径和行为都通过配置控制
3. **类型安全**: 使用强类型配置,编译时验证
4. **可维护性**: 每个数据源的逻辑独立,互不影响
5. **可测试性**: Provider可独立测试易于Mock
## 注意事项
1. Provider必须实现 `IScopedDependency` 才能被自动注册
2. `GetTables()` 中需要标记Schema以区分数据源`t.Schema += "." + DatabaseKey`
3. 路径模板中的占位符大小写敏感
4. Order属性控制数据源的显示顺序数字越小越靠前
5. NamingStrategy影响实体类的命名需根据数据库命名规范选择
## 扩展性考虑
当前架构支持以下扩展:
- 新的命名策略需扩展EntityNamingStrategy枚举
- 自定义路径占位符需扩展PathResolver
- 不同的模板引擎(需修改代码生成服务)
- 多租户数据源需在Provider中实现动态配置

View File

@ -28,6 +28,7 @@
<ProjectReference Include="..\MiaoYu.Core\MiaoYu.Core.csproj" />
<ProjectReference Include="..\MiaoYu.Repository.Admin\MiaoYu.Repository.Admin.csproj" />
<ProjectReference Include="..\MiaoYu.Repository.ChatAI.Admin\MiaoYu.Repository.ChatAI.Admin.csproj" />
<ProjectReference Include="..\MiaoYu.Repository.LiveForum.Admin\MiaoYu.Repository.LiveForum.Admin.csproj" />
<ProjectReference Include="..\MiaoYu.Shared.Admin\MiaoYu.Shared.Admin.csproj" />
<ProjectReference Include="..\MiaoYu.Shared\MiaoYu.Shared.csproj" />
</ItemGroup>

View File

@ -1384,6 +1384,199 @@
</summary>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig">
<summary>
数据源配置
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.DatabaseKey">
<summary>
数据库标识Admin, MiaoYuChat, LiveForum
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.DisplayName">
<summary>
显示名称
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.EntityNamespace">
<summary>
实体项目命名空间
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ModelPathTemplate">
<summary>
实体类路径模板(支持占位符:{RootPath}, {Namespace}, {EntityName}, {EntityNamePlural}, {TableName}
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ServicePathTemplate">
<summary>
服务层路径模板
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ControllerPathTemplate">
<summary>
控制器路径模板
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientIndexPathTemplate">
<summary>
前端Index页面路径模板
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientInfoPathTemplate">
<summary>
前端Info页面路径模板
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.ClientServicePathTemplate">
<summary>
前端Service路径模板
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.TemplatePath">
<summary>
代码生成模板目录
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.NamingStrategy">
<summary>
实体类命名规则(保持原名 or 驼峰转换)
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig.Order">
<summary>
排序权重(数字越小越靠前)
</summary>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants">
<summary>
数据源常量
</summary>
</member>
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.Admin">
<summary>
后台管理系统数据库
</summary>
</member>
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.MiaoYuChat">
<summary>
喵语AI聊天数据库
</summary>
</member>
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConstants.LiveForum">
<summary>
直播论坛数据库(预留)
</summary>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy">
<summary>
实体命名策略
</summary>
</member>
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy.KeepOriginal">
<summary>
保持数据库表名原样
</summary>
</member>
<member name="F:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy.ToPascalCase">
<summary>
转换为驼峰命名(去除前缀下划线)
</summary>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider">
<summary>
数据源提供者接口
</summary>
</member>
<member name="P:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.Config">
<summary>
数据源配置
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.GetTables">
<summary>
获取该数据源的所有表信息
</summary>
<returns>表信息列表</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider.GetDbContext">
<summary>
获取DbContext用于获取FreeSql实例
</summary>
<returns>数据库上下文</returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions">
<summary>
数据源扩展方法
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions.ExtractDatabaseKey(System.String)">
<summary>
从 Schema 中提取数据库标识
</summary>
<param name="schema">Schema字符串</param>
<returns>数据库标识</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceExtensions.CleanSchema(System.String)">
<summary>
清理 Schema移除数据库标识
</summary>
<param name="schema">Schema字符串</param>
<returns>清理后的Schema</returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager">
<summary>
数据源管理器
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.#ctor(System.Collections.Generic.IEnumerable{MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.IDataSourceProvider})">
<summary>
构造函数通过依赖注入自动收集所有IDataSourceProvider实现
</summary>
<param name="providers">所有数据源提供者</param>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetAllProviders">
<summary>
获取所有数据源提供者
</summary>
<returns>数据源提供者集合</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetProvider(System.String)">
<summary>
根据数据库标识获取数据源提供者
</summary>
<param name="databaseKey">数据库标识Admin, MiaoYuChat</param>
<returns>数据源提供者如果未找到返回null</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager.GetAllTables">
<summary>
获取所有数据源的表信息
</summary>
<returns>所有表信息列表</returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver">
<summary>
路径解析器
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver.ResolvePath(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.DataSourceConfig,System.String)">
<summary>
解析路径模板
</summary>
<param name="template">路径模板(支持占位符)</param>
<param name="config">数据源配置</param>
<param name="tableName">表名</param>
<returns>解析后的完整路径</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver.GetEntityName(System.String,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Abstractions.EntityNamingStrategy)">
<summary>
根据命名策略获取实体名
</summary>
<param name="tableName">表名</param>
<param name="strategy">命名策略</param>
<returns>实体名</returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.ICodeGenerationService">
<summary>
代码生成服务
@ -1504,13 +1697,15 @@
代码生成服务
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.#ctor(MiaoYu.Shared.Admin.ApplicationServices.IDatabaseTableService,MiaoYu.Core.Razor.Services.IRazorViewRender,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.#ctor(MiaoYu.Shared.Admin.ApplicationServices.IDatabaseTableService,MiaoYu.Core.Razor.Services.IRazorViewRender,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager,MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.PathResolver)">
<summary>
构造函数
</summary>
<param name="databaseTableService"></param>
<param name="razorViewRender"></param>
<param name="webHostEnvironment"></param>
<param name="databaseTableService">数据库表服务</param>
<param name="razorViewRender">Razor视图渲染器</param>
<param name="webHostEnvironment">Web宿主环境</param>
<param name="dataSourceManager">数据源管理器</param>
<param name="pathResolver">路径解析器</param>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetGenContextDtos(System.Int32,System.Int32,MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
@ -1526,9 +1721,10 @@
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.FillPathByLowCodeTable(MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable)">
<summary>
根据 lowCodeTable 填充路径
根据 lowCodeTable 填充路径(支持多数据源)
</summary>
<returns></returns>
<param name="lowCodeTable">低代码表配置</param>
<returns>填充路径后的低代码表配置</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GetGenContextDto(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
@ -1539,42 +1735,42 @@
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenModelAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成model
生成model(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenServiceAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成service
生成service(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenControllerAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成controller
生成controller(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenServiceJsAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成service js
生成service js(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenIndexAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成 index vue
生成 index vue(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.CodeGenerationService.GenInfoAsync(MiaoYu.Api.Admin.Models.Dtos.DevelopmentTool.GenFormDto)">
<summary>
生成 info vue
生成 info vue(支持多数据源)
</summary>
<param name="genFormDto"></param>
<returns></returns>
@ -1672,19 +1868,21 @@
数据库表服务
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.#ctor(Microsoft.Extensions.Caching.Memory.IMemoryCache,HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config})">
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.#ctor(Microsoft.Extensions.Caching.Memory.IMemoryCache,HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTableInfo},HZY.Framework.Repository.EntityFramework.IRepository{MiaoYu.Repository.ChatAI.Admin.Entities.T_Image_Config},MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Core.DataSourceManager)">
<summary>
构造函数
</summary>
<param name="memoryCache"></param>
<param name="lowCodeTableRepository"></param>
<param name="lowCodeTableInfoRepository"></param>
<param name="memoryCache">内存缓存</param>
<param name="lowCodeTableRepository">低代码表仓储</param>
<param name="lowCodeTableInfoRepository">低代码表字段仓储</param>
<param name="imageConfig">图片配置仓储</param>
<param name="dataSourceManager">数据源管理器</param>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetAllTableInfos">
<summary>
获取所有的表 包含表下面的列
获取所有的表 包含表下面的列(支持多数据源)
</summary>
<returns></returns>
<returns>所有表信息列表</returns>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.DatabaseTableService.GetAllTables">
<summary>
@ -1765,7 +1963,7 @@
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.SynchronizationAsync">
<summary>
同步表
同步表(支持多数据源)
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Impl.LowCodeTableService.ChangeAsync(System.Collections.Generic.List{MiaoYu.Repository.Admin.Entities.LowCode.LowCodeTable})">
@ -1789,6 +1987,16 @@
<param name="form"></param>
<returns></returns>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers.AdminDataSourceProvider">
<summary>
Admin 数据源提供者
</summary>
</member>
<member name="T:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.LowCode.Providers.MiaoYuChatDataSourceProvider">
<summary>
MiaoYuChat 数据源提供者
</summary>
</member>
<member name="M:MiaoYu.Api.Admin.ApplicationServices.DevelopmentTools.MonitorEFCore.IMonitorEFCoreService.GetEFCoreMonitorContext">
<summary>
获取 EFCore 监控上下文

View File

@ -1,4 +1,4 @@
{
{
"profiles": {
"http": {
"commandName": "Project",
@ -9,4 +9,5 @@
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:5500"
}
}
}

View File

@ -2,7 +2,7 @@
//
"ConnectionStrings": {
// redis
"Redis": "124.220.55.158:6379,defaultDatabase=10"
"Redis": "192.168.195.15:6379,defaultDatabase=10"
},
// pi
"AdminRepositoryOptions": {
@ -14,7 +14,7 @@
//"ConnectionString": "Server=localhost; port=3306; Database=hzy_admin_mysql_20230227; uid=root; pwd=123456; Convert Zero Datetime=False"
//// - sqlserver
//"ConnectionString": "Server=192.168.195.2;Database=MiaoYu;User ID=zpc;Password=zpc;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
"ConnectionString": "Server=192.168.1.17;Database=HZY;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
"ConnectionString": "Server=192.168.195.15;Database=HZY;User Id=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
//// - postgresql
//"ConnectionString": "User ID=postgres;Password=123456;Host=localhost;Port=5432;Database=hzy_microservices_pgsql_20230227;Pooling=true;TimeZone=Asia/Shanghai",
//// - oracle
@ -25,7 +25,15 @@
"DefaultDatabaseType": "SqlServer",
//EFCore
"IsMonitorEFCore": true,
"ConnectionString": "Server=192.168.195.2;Database=MiaoYu;User ID=zpc;Password=zpc;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
"ConnectionString": "Server=192.168.195.15;Database=MiaoYu;User ID=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
},
"LiveForumAdminRepositoryOptions": {
// SqlServer MySql
"DefaultDatabaseType": "SqlServer",
//EFCore
"IsMonitorEFCore": true,
"ConnectionString": "Server=192.168.195.15;Database=LiveForumDB;User ID=sa;Password=Dbt@com@123;MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;"
},
//

View File

@ -1,5 +1,5 @@
namespace MiaoYu.Repository.ChatAI.Admin.Models;
public class ChatAdminRepositoryOptions : RepositoryOptions
{

View File

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Rougamo />
</Weavers>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Rougamo" minOccurs="0" maxOccurs="1" type="xs:anyType" />
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -0,0 +1,44 @@
namespace MiaoYu.Repository.LiveForum.Admin
{
/// <summary>
/// 后台管理系统数据库上下文
/// </summary>
[DbContextConfig($"Repository.*.Entities.*")]
public class LiveForumAdminDbContext : DbContext, IBaseDbContext
{
/// <summary>
/// 工作单元
/// </summary>
public IUnitOfWork UnitOfWork { get; }
public LiveForumAdminDbContext(DbContextOptions<LiveForumAdminDbContext> dbContextOptions) : base(dbContextOptions)
{
UnitOfWork = new UnitOfWorkImpl<LiveForumAdminDbContext>(this);
}
/// <summary>
/// 模型创建
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region
//OnModelCreatingPartial(modelBuilder);
//ModelBuilderExtensions.Seed(modelBuilder);
#endregion
var dbContextConfigAttribute = GetType().GetCustomAttribute<DbContextConfigAttribute>()!;
var t = dbContextConfigAttribute.GetModelTypes(GetType());
dbContextConfigAttribute!.OnModelCreating(modelBuilder, t);
}
}
}

View File

@ -0,0 +1,138 @@
namespace MiaoYu.Repository.LiveForum.Admin
{
/// <summary>
/// 程序启动器
/// </summary>
[ImportStartupModule<CoreEntityFrameworkStartup>]
public class LiveForumAdminRepositoryStartup : StartupModule<LiveForumAdminRepositoryStartup>
{
/// <summary>
/// 程序启动器
/// </summary>
/// <param name="webApplicationBuilder"></param>
public override void ConfigureServices(WebApplicationBuilder webApplicationBuilder)
{
var configuration = webApplicationBuilder.Configuration;
var services = webApplicationBuilder.Services;
var webHostEnvironment = webApplicationBuilder.Environment;
var repositoriesOptions = configuration
.GetSection(nameof(LiveForumAdminRepositoryOptions))
.Get<LiveForumAdminRepositoryOptions>() ?? throw new Exception("配置对象 空 异常!");
var connectionString = repositoriesOptions?.ConnectionString;
connectionString = string.IsNullOrWhiteSpace(connectionString) ?
configuration["ConnectionStrings:" + repositoriesOptions!.DefaultDatabaseType.ToString()] :
connectionString;
services.AddDbContextFactory<LiveForumAdminDbContext>(optionsBuilder =>
{
switch (repositoriesOptions.DefaultDatabaseType)
{
case DefaultDatabaseType.SqlServer:
optionsBuilder
.UseSqlServer(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
;
break;
case DefaultDatabaseType.MySql:
optionsBuilder
.UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion, w => w.MinBatchSize(1).MaxBatchSize(1000))
;
break;
case DefaultDatabaseType.PostgreSql:
//EnableLegacyTimestampBehavior 启动旧行为,避免时区问题,存储时间报错
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
optionsBuilder
.UseNpgsql(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
;
break;
case DefaultDatabaseType.Oracle:
optionsBuilder
.UseOracle(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
;
break;
default:
break;
}
if (webHostEnvironment.IsDevelopment())
{
var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
// sql 日志写入控制台
optionsBuilder.UseLoggerFactory(loggerFactory);
}
// 懒加载代理
//options.UseLazyLoadingProxies();
//添加 EFCore 监控 和 动态表名
optionsBuilder.AddEntityFrameworkMonitor(repositoriesOptions.IsMonitorEFCore);
optionsBuilder.AddInterceptors(new AuditInterceptor());
});
services.AddEntityFrameworkRepositories<LiveForumAdminDbContext>(repositoriesOptions, (auditOptions) =>
{
// 你的自定义审计字段 ...
//auditOptions.Add(new AuditOptions()
//{
// CreationTimeFieldName = nameof(ICreateEntityV2.CreateTime),
// CreatorUserIdFieldName = "",
// LastModificationTimeFieldName = nameof(IUpdateEntityV2.UpdateTime),
// LastModifierUserIdFieldName = "",
// DeletionTimeFieldName = "UpdateTime",
// DeleterUserIdFieldName = "UpdateBy",
// IsDeletedFieldName = "DelFlag",
//});
}, (freesqlOptions) =>
{
freesqlOptions.FreeSqlAuditAopList?.Add(new FreeSqlAuditAop());
freesqlOptions.FreeSqlAction = (freeSql) =>
{
freeSql.Aop.CurdAfter += (object? sender, FreeSql.Aop.CurdAfterEventArgs curdAfter) =>
{
var stringBuilder = new StringBuilder();
stringBuilder.Append($"\r\n====[FreeSql 开始 耗时: {curdAfter.ElapsedMilliseconds} ms]=========");
stringBuilder.Append($"\r\n{curdAfter.Sql}");
stringBuilder.Append($"\r\n====[FreeSql 结束 线程Id:{Environment.CurrentManagedThreadId}]=========");
LogUtil.Log.Warning(stringBuilder.ToString());
};
};
});
}
/// <summary>
/// Configure
/// </summary>
/// <param name="webApplication"></param>
public override void Configure(WebApplication webApplication)
{
// 使用 DbContext
#region
//if (webApplication.Environment.IsDevelopment())
//{
// // 自动迁移 (如果迁移文件有变动)
// using var scope = webApplication.Services.CreateScope();
// using var adminDbContext = scope.ServiceProvider.GetService<ChatAdminDbContext>();
// if (adminDbContext!.Database.GetPendingMigrations().Count() > 0)
// {
// try
// {
// adminDbContext.Database.Migrate();
// }
// catch (Exception ex)
// {
// LogUtil.Log.Error(ex.Message, ex);
// }
// }
//}
#endregion
}
}
}

View File

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>$(MSBuildProjectName).xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Rougamo.Fody" Version="2.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MiaoYu.Core.EntityFramework\MiaoYu.Core.EntityFramework.csproj" />
<ProjectReference Include="..\MiaoYu.Core.Logs\MiaoYu.Core.Logs.csproj" />
<ProjectReference Include="..\MiaoYu.Core.Quartz\MiaoYu.Core.Quartz.csproj" />
<ProjectReference Include="..\MiaoYu.Core\MiaoYu.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Entities\" />
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>MiaoYu.Repository.LiveForum.Admin</name>
</assembly>
<members>
<member name="T:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminDbContext">
<summary>
后台管理系统数据库上下文
</summary>
</member>
<member name="P:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminDbContext.UnitOfWork">
<summary>
工作单元
</summary>
</member>
<member name="M:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminDbContext.OnModelCreating(Microsoft.EntityFrameworkCore.ModelBuilder)">
<summary>
模型创建
</summary>
<param name="modelBuilder"></param>
</member>
<member name="T:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminRepositoryStartup">
<summary>
程序启动器
</summary>
</member>
<member name="M:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminRepositoryStartup.ConfigureServices(Microsoft.AspNetCore.Builder.WebApplicationBuilder)">
<summary>
程序启动器
</summary>
<param name="webApplicationBuilder"></param>
</member>
<member name="M:MiaoYu.Repository.LiveForum.Admin.LiveForumAdminRepositoryStartup.Configure(Microsoft.AspNetCore.Builder.WebApplication)">
<summary>
Configure
</summary>
<param name="webApplication"></param>
</member>
</members>
</doc>

View File

@ -0,0 +1,6 @@
public class LiveForumAdminRepositoryOptions : RepositoryOptions
{
}

View File

@ -0,0 +1,27 @@
global using MiaoYu.Core.EntityFramework;
global using MiaoYu.Core.EntityFramework.Interceptors;
global using MiaoYu.Core.Quartz.Models;
global using HZY.Framework.Core.AspNetCore;
global using HZY.Framework.Core.Quartz;
global using HZY.Framework.Repository.EntityFramework;
global using HZY.Framework.Repository.EntityFramework.Attributes;
global using HZY.Framework.Repository.EntityFramework.Models;
global using HZY.Framework.Repository.EntityFramework.Models.Enums;
global using HZY.Framework.Repository.EntityFramework.Models.Standard;
global using HZY.Framework.Repository.EntityFramework.Repositories;
global using HZY.Framework.Repository.EntityFramework.Repositories.Impl;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.EntityFrameworkCore;
global using Microsoft.EntityFrameworkCore.Infrastructure;
global using Microsoft.Extensions.Caching.Memory;
global using Microsoft.Extensions.Configuration;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using System.ComponentModel.DataAnnotations;
global using System.ComponentModel.DataAnnotations.Schema;
global using System.Reflection;
global using MiaoYu.Core.Logs;
global using System.Text;
global using MiaoYu.Core.EntityFramework.Models;