Blame view

Yi.Abp.Net8/src/Yi.Abp.Application/Services/TestService.cs 10.4 KB
515fceeb   “wangming”   框架初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  using Mapster;
  using Medallion.Threading;
  using Microsoft.AspNetCore.Authorization;
  using Microsoft.AspNetCore.Mvc;
  using Volo.Abp.Application.Services;
  using Volo.Abp.Data;
  using Volo.Abp.DistributedLocking;
  using Volo.Abp.Domain.Repositories;
  using Volo.Abp.MultiTenancy;
  using Volo.Abp.Settings;
  using Volo.Abp.Uow;
  using Yi.Framework.Rbac.Domain.Authorization;
  using Yi.Framework.Rbac.Domain.Entities;
  using Yi.Framework.Rbac.Domain.Extensions;
  using Yi.Framework.SettingManagement.Domain;
  using Yi.Framework.SqlSugarCore.Abstractions;
  
  namespace Yi.Abp.Application.Services
  {
      /// <summary>
      /// 常用魔改及扩展示例
      /// </summary>
      public class TestService : ApplicationService
      {
          // /// <summary>
          // /// 属性注入
          // /// 不推荐,坑太多,容易把自己玩死,简单的东西可以用一用
          // /// </summary>
          public ISqlSugarRepository<ConfigAggregateRoot> sqlSugarRepository { get; set; }
  
          /// <summary>
          /// </summary>
          /// <param name="name"></param>
          /// <returns></returns>
          [HttpGet("hello-world")]
          public string GetHelloWorld(string? name)
          {
              //会自动添加前缀,而不是重置,更符合习惯
              //如果需要重置以"/"根目录开头即可
              //你好世界
              return name ?? "HelloWord";
          }
  
          /// <summary>
          /// 异常处理
          /// </summary>
          /// <returns></returns>
          [HttpGet("error")]
          public string GetError()
          {
              throw new UserFriendlyException("业务异常");
              throw new Exception("系统异常");
          }
  
          /// <summary>
          /// SqlSugar
          /// </summary>
          /// <returns></returns>
          public async Task<object> GetSqlSugarDbAsync()
          {
              //用户体验优先,可直接使用Db操作,依赖抽象
              return await sqlSugarRepository._DbQueryable.ToListAsync();
          }
  
          /// <summary>
          /// 工作单元
          /// </summary>
          /// <returns></returns>
          public async Task GetUowAsync()
          {
              //魔改
              // 用户体验优先,万金油模式,支持高并发。支持单、多线程并发安全,支持多线程工作单元,支持。。。
              // 不支持多线程无工作单元,应由工作单元统一管理(来自abp工作单元设计)
              // 请注意,如果requiresNew: true只有在没有工作单元内使用,嵌套子工作单元,默认值false即可
              // 自动在各个情况处理db客户端最优解之一
              int i = 3;
              List<Task> tasks = new List<Task>();
              await sqlSugarRepository.GetListAsync();
              await sqlSugarRepository.GetListAsync();
              while (i > 0)
              {
                  tasks.Add(Task.Run(async () =>
                  {
                      //以下操作是错误的,不允许在新线程中,直接操作db,所有db操作应放在工作单元内,应由工作单元统一管理-来自abp工作单元设计
                      //await sqlSugarRepository.InsertAsync(new BannerAggregateRoot { Name = "插入2" });
                      using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
                      {
                          await sqlSugarRepository.InsertAsync(new ConfigAggregateRoot { ConfigKey = "插入1" });
                          await uow.CompleteAsync();
                      }
                  }));
                  await sqlSugarRepository.InsertAsync(new ConfigAggregateRoot { ConfigKey = "插入3" });
                  i--;
              }
  
              await Task.WhenAll(tasks);
          }
  
          /// <summary>
          /// 当前用户
          /// </summary>
          /// <returns></returns>
          public void GetCurrentUser()
          {
              //token鉴权之后,可以直接获取
              if (CurrentUser.Id is not null)
              {
                  //权限
                  CurrentUser.GetPermissions();
  
                  //角色信息
                  CurrentUser.GetRoleInfo();
  
                  //部门id
                  CurrentUser.GetDeptId();
              }
          }
  
          /// <summary>
          /// 数据权限
          /// </summary>
          public void GetDataFilter()
          {
              //这里会数据权限过滤
              using (DataFilter.DisablePermissionHandler())
              {
                  //这里不会数据权限过滤
              }
              //这里会数据权限过滤
          }
  
          /// <summary>
          /// 对象映射
          /// </summary>
          public void GetMapper()
          {
              //直接无脑Adapt,无需配置
              var entity = new ConfigAggregateRoot();
              var dto = entity.Adapt<ConfigAggregateRoot>();
          }
  
          private static int RequestNumber { get; set; } = 0;
  
          /// <summary>
          /// 速率限制
          /// </summary>
          /// <returns></returns>
          // [DisableRateLimiting]
          //[EnableRateLimiting("sliding")]
          public int GetRateLimiting()
          {
              RequestNumber++;
              return RequestNumber;
          }
  
  
          public ISettingProvider _settingProvider { get; set; }
  
          public ISettingManager _settingManager { get; set; }
  
          /// <summary>
          /// 系统配置模块
          /// </summary>
          /// <returns></returns>
          public async Task<string> GetSettingAsync()
          {
              //DDD需要提前定义
              //默认来说,不提供修改操作,配置应该独立
              var enableOrNull = await _settingProvider.GetOrNullAsync("DDD");
  
              //如果要进行修改,可使用yi.framework下的ISettingManager
              await _settingManager.SetGlobalAsync("DDD", "false");
  
              var enableOrNull2 = await _settingManager.GetOrNullGlobalAsync("DDD");
  
              //当然,他的独特地方,是支持来自多个模块,例如配置文件?
              var result = await _settingManager.GetOrNullConfigurationAsync("Test");
  
  
              return result ?? string.Empty;
          }
  
          
          /// <summary>
          /// 分布式送abp版本:abp套了一层娃。但是纯粹鸡肋,不建议使用这个
          /// </summary>
          public IAbpDistributedLock AbpDistributedLock => LazyServiceProvider.LazyGetService<IAbpDistributedLock>();
  
          /// <summary>
          /// 分布式锁推荐使用版本:yyds,分布式锁永远的神!
          /// </summary>
          public IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetService<IDistributedLockProvider>();
  
          /// <summary>
          /// 分布式锁
          /// </summary>
          /// <remarks>强烈吐槽一下abp,正如他们所说,abp的分布式锁单纯为了自己用,一切还是以DistributedLock为主</remarks>>
          /// <returns></returns>
          public async Task<string> GetDistributedLockAsync()
          {
              var number = 0;
              await Parallel.ForAsync(0, 100, async (i, cancellationToken) =>
              {
                  await using (await DistributedLock.AcquireLockAsync("MyLockName"))
                  {
                      //执行1
                      number += 1;
                  }
              });
              var number2 = 0;
              await Parallel.ForAsync(0, 100, async (i, cancellationToken) =>
              {
                      //执行1
                      number2 += 1;
              });
              return $"加锁结果:{number},不加锁结果:{number2}";
          }
  
          public ICurrentTenant CurrentTenant { get; set; }
          public IRepository<ConfigAggregateRoot> repository { get; set; }
          public IDataSeeder DataSeeder { get; set; }
          /// <summary>
          /// 多租户
          /// </summary>
          /// <returns></returns>
          public async Task<string>  GetMultiTenantAsync()
          {
              using (var uow=UnitOfWorkManager.Begin())
              {
                  //此处会实例化一个db,连接默认库
                  var defautTenantData1= await repository.GetListAsync();
                  using (CurrentTenant.Change(null,"Default"))
                  {
                      var defautTenantData2= await repository.GetListAsync();
                      await repository.InsertAsync(new ConfigAggregateRoot
                      {
                          ConfigKey = "default",
                      });
                      var defautTenantData3= await repository.GetListAsync(x=>x.ConfigKey=="default");
                  }
                  //此处会实例化一个新的db连接MES
                  using (CurrentTenant.Change(null,"Mes"))
                  {
                      var otherTenantData1= await repository.GetListAsync();
                      await repository.InsertAsync(new ConfigAggregateRoot
                      {
                          ConfigKey = "Mes1",
                      });
                      var otherTenantData2= await repository.GetListAsync(x=>x.ConfigKey=="Mes1");
                  }
                  //此处会复用Mesdb,不会实例化新的db
                  using (CurrentTenant.Change(Guid.Parse("33333333-3d72-4339-9adc-845151f8ada0")))
                  {
                      var otherTenantData1= await repository.GetListAsync();
                      await repository.InsertAsync(new ConfigAggregateRoot
                      {
                          ConfigKey = "Mes2",
                      });
                      var otherTenantData2= await repository.GetListAsync(x=>x.ConfigKey=="Mes2");
                  }
                  //此处会将多库进行一起提交,前面的操作有报错,全部回滚
                  await uow.CompleteAsync();
                  return "根据租户切换不同的数据库,并管理db实例连接,涉及多库事务统一到最后提交";
              }
           
          }
  
          /// <summary>
          /// 手动执行种子数据初始化(临时接口,用于解决用户数据不存在问题)
          /// </summary>
          /// <returns></returns>
          [HttpPost("seed-data")]
          [AllowAnonymous]
          public async Task<string> PostSeedDataAsync()
          {
              try
              {
                  await DataSeeder.SeedAsync();
7cb07aab   “wangming”   Update default ad...
279
                  return "种子数据初始化成功!默认管理员账号:admin / 123456";
515fceeb   “wangming”   框架初始化
280
281
282
283
284
285
286
287
              }
              catch (Exception ex)
              {
                  return $"种子数据初始化失败:{ex.Message}";
              }
          }
      }
  }