Blame view

美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/PartnerAppService.cs 13.7 KB
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
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
  using FoodLabeling.Application.Helpers;
  using FoodLabeling.Application.Contracts.Dtos.Common;
  using FoodLabeling.Application.Contracts.Dtos.Partner;
  using FoodLabeling.Application.Contracts.IServices;
  using FoodLabeling.Application.Services.DbModels;
  using Microsoft.AspNetCore.Mvc;
  using QuestPDF.Fluent;
  using QuestPDF.Helpers;
  using QuestPDF.Infrastructure;
  using SqlSugar;
  using Volo.Abp;
  using Volo.Abp.Application.Services;
  using Volo.Abp.Guids;
  using Volo.Abp.Uow;
  using Yi.Framework.SqlSugarCore.Abstractions;
  
  namespace FoodLabeling.Application.Services;
  
  /// <summary>
  /// 合作伙伴管理(fl_partner
  /// </summary>
  public class PartnerAppService : ApplicationService, IPartnerAppService
  {
      private const int ExportPdfMaxRows = 5000;
  
      private readonly ISqlSugarDbContext _dbContext;
      private readonly IGuidGenerator _guidGenerator;
  
      public PartnerAppService(ISqlSugarDbContext dbContext, IGuidGenerator guidGenerator)
      {
          _dbContext = dbContext;
          _guidGenerator = guidGenerator;
      }
  
      /// <inheritdoc />
      public async Task<PagedResultWithPageDto<PartnerGetListOutputDto>> GetListAsync(PartnerGetListInputVo input)
      {
          RefAsync<int> total = 0;
10fd1324   李曜臣   5-17接口优化
39
          var query = await BuildPartnerListQueryAsync(input);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
40
41
42
43
44
45
46
  
          var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
          var items = entities.Select(MapListItem).ToList();
          return BuildPagedResult(input.SkipCount, input.MaxResultCount, total, items);
      }
  
      /// <inheritdoc />
10fd1324   李曜臣   5-17接口优化
47
      public async Task<PartnerGetOutputDto> GetAsync(Guid id)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
48
      {
10fd1324   李曜臣   5-17接口优化
49
          if (id == Guid.Empty)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
50
          {
10fd1324   李曜臣   5-17接口优化
51
              throw new UserFriendlyException("Partner id is required.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
52
53
          }
  
10fd1324   李曜臣   5-17接口优化
54
          var partnerId = id.ToString();
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
55
56
57
58
          var entity = await _dbContext.SqlSugarClient.Queryable<FlPartnerDbEntity>()
              .FirstAsync(x => !x.IsDeleted && x.Id == partnerId);
          if (entity is null)
          {
10fd1324   李曜臣   5-17接口优化
59
              throw new UserFriendlyException("Partner not found.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
60
61
62
63
64
65
66
67
68
69
70
71
          }
  
          return MapDetail(entity);
      }
  
      /// <inheritdoc />
      [UnitOfWork]
      public async Task<PartnerGetOutputDto> CreateAsync(PartnerCreateInputVo input)
      {
          var name = input.PartnerName?.Trim();
          if (string.IsNullOrWhiteSpace(name))
          {
10fd1324   李曜臣   5-17接口优化
72
              throw new UserFriendlyException("Partner name is required.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
73
74
75
76
77
          }
  
          var email = input.ContactEmail?.Trim();
          if (!string.IsNullOrWhiteSpace(email) && !IsPlausibleEmail(email))
          {
10fd1324   李曜臣   5-17接口优化
78
              throw new UserFriendlyException("Invalid contact email format.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
79
80
81
82
83
84
85
86
87
          }
  
          var now = Clock.Now;
          var entity = new FlPartnerDbEntity
          {
              Id = _guidGenerator.Create().ToString(),
              IsDeleted = false,
              PartnerName = name,
              ContactEmail = string.IsNullOrWhiteSpace(email) ? null : email,
10fd1324   李曜臣   5-17接口优化
88
              PhoneNumber = TrimToNull(input.PhoneNumber),
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
89
90
91
92
93
94
              State = input.State,
              CreationTime = now,
              CreatorId = CurrentUser?.Id?.ToString(),
              LastModificationTime = now,
              LastModifierId = CurrentUser?.Id?.ToString()
          };
10fd1324   李曜臣   5-17接口优化
95
          ApplyAddressFields(entity, input);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
96
97
  
          await _dbContext.SqlSugarClient.Insertable(entity).ExecuteCommandAsync();
10fd1324   李曜臣   5-17接口优化
98
          return await GetAsync(Guid.Parse(entity.Id));
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
99
100
101
102
      }
  
      /// <inheritdoc />
      [UnitOfWork]
10fd1324   李曜臣   5-17接口优化
103
      public async Task<PartnerGetOutputDto> UpdateAsync(Guid id, PartnerUpdateInputVo input)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
104
      {
10fd1324   李曜臣   5-17接口优化
105
          if (id == Guid.Empty)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
106
          {
10fd1324   李曜臣   5-17接口优化
107
              throw new UserFriendlyException("Partner id is required.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
108
109
          }
  
10fd1324   李曜臣   5-17接口优化
110
          var partnerId = id.ToString();
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
111
112
113
114
          var entity = await _dbContext.SqlSugarClient.Queryable<FlPartnerDbEntity>()
              .FirstAsync(x => !x.IsDeleted && x.Id == partnerId);
          if (entity is null)
          {
10fd1324   李曜臣   5-17接口优化
115
              throw new UserFriendlyException("Partner not found.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
116
117
118
119
120
          }
  
          var name = input.PartnerName?.Trim();
          if (string.IsNullOrWhiteSpace(name))
          {
10fd1324   李曜臣   5-17接口优化
121
              throw new UserFriendlyException("Partner name is required.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
122
123
124
125
126
          }
  
          var email = input.ContactEmail?.Trim();
          if (!string.IsNullOrWhiteSpace(email) && !IsPlausibleEmail(email))
          {
10fd1324   李曜臣   5-17接口优化
127
              throw new UserFriendlyException("Invalid contact email format.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
128
129
130
131
          }
  
          entity.PartnerName = name;
          entity.ContactEmail = string.IsNullOrWhiteSpace(email) ? null : email;
10fd1324   李曜臣   5-17接口优化
132
          entity.PhoneNumber = TrimToNull(input.PhoneNumber);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
133
          entity.State = input.State;
10fd1324   李曜臣   5-17接口优化
134
          ApplyAddressFields(entity, input);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
135
136
137
138
          entity.LastModificationTime = Clock.Now;
          entity.LastModifierId = CurrentUser?.Id?.ToString();
  
          await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
10fd1324   李曜臣   5-17接口优化
139
          return await GetAsync(id);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
140
141
142
143
      }
  
      /// <inheritdoc />
      [UnitOfWork]
10fd1324   李曜臣   5-17接口优化
144
      public async Task DeleteAsync(Guid id)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
145
      {
10fd1324   李曜臣   5-17接口优化
146
          if (id == Guid.Empty)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
147
          {
10fd1324   李曜臣   5-17接口优化
148
              throw new UserFriendlyException("Partner id is required.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
149
150
          }
  
10fd1324   李曜臣   5-17接口优化
151
          var partnerId = id.ToString();
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
152
153
154
155
          var entity = await _dbContext.SqlSugarClient.Queryable<FlPartnerDbEntity>()
              .FirstAsync(x => !x.IsDeleted && x.Id == partnerId);
          if (entity is null)
          {
10fd1324   李曜臣   5-17接口优化
156
              throw new UserFriendlyException("Partner not found.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
157
158
159
160
161
162
163
164
165
          }
  
          entity.IsDeleted = true;
          entity.LastModificationTime = Clock.Now;
          entity.LastModifierId = CurrentUser?.Id?.ToString();
          await _dbContext.SqlSugarClient.Updateable(entity).ExecuteCommandAsync();
      }
  
      /// <inheritdoc />
10fd1324   李曜臣   5-17接口优化
166
167
      [HttpGet]
      public async Task<IActionResult> ExportPdfAsync([FromQuery] PartnerGetListInputVo input)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
168
169
170
      {
          QuestPDF.Settings.License = LicenseType.Community;
  
10fd1324   李曜臣   5-17接口优化
171
172
          var count = await (await BuildPartnerListQueryAsync(input)).CountAsync();
          var query = await BuildPartnerListQueryAsync(input);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
173
174
          if (count > ExportPdfMaxRows)
          {
10fd1324   李曜臣   5-17接口优化
175
176
              throw new UserFriendlyException(
                  $"Export exceeds the maximum of {ExportPdfMaxRows} rows. Narrow your filters and try again.");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
177
178
179
          }
  
          var rows = await query.Take(ExportPdfMaxRows).ToListAsync();
a7684ddb   李曜臣   批量导入导出,批量编辑
180
          var fileName = $"companies_{Clock.Now:yyyy-MM-dd_HH-mm-ss}.pdf";
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
181
182
183
184
185
186
187
  
          var document = Document.Create(container =>
          {
              container.Page(page =>
              {
                  page.Margin(28);
                  page.DefaultTextStyle(x => x.FontSize(10));
a7684ddb   李曜臣   批量导入导出,批量编辑
188
                  page.Header().Text("Companies").SemiBold().FontSize(18);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
189
190
191
192
193
194
195
196
197
198
199
200
201
202
                  page.Content().PaddingTop(12).Table(table =>
                  {
                      table.ColumnsDefinition(c =>
                      {
                          c.RelativeColumn(2.2f);
                          c.RelativeColumn(2.4f);
                          c.RelativeColumn(1.8f);
                          c.RelativeColumn(1f);
                          c.RelativeColumn(1.6f);
                      });
  
                      static IContainer CellHeader(IContainer c) =>
                          c.Background(Colors.Grey.Lighten3).Padding(6).DefaultTextStyle(x => x.SemiBold());
  
a7684ddb   李曜臣   批量导入导出,批量编辑
203
                      table.Cell().Element(CellHeader).Text("Company");
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
204
205
206
207
208
209
210
211
212
213
214
                      table.Cell().Element(CellHeader).Text("Contact");
                      table.Cell().Element(CellHeader).Text("Phone");
                      table.Cell().Element(CellHeader).Text("Status");
                      table.Cell().Element(CellHeader).Text("Created");
  
                      foreach (var e in rows)
                      {
                          var status = e.State ? "active" : "inactive";
                          table.Cell().BorderBottom(0.5f).BorderColor(Colors.Grey.Lighten2).Padding(5)
                              .Text(e.PartnerName ?? string.Empty);
                          table.Cell().BorderBottom(0.5f).BorderColor(Colors.Grey.Lighten2).Padding(5)
10fd1324   李曜臣   5-17接口优化
215
                              .Text(string.IsNullOrWhiteSpace(e.ContactEmail) ? "None" : e.ContactEmail!);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
216
                          table.Cell().BorderBottom(0.5f).BorderColor(Colors.Grey.Lighten2).Padding(5)
10fd1324   李曜臣   5-17接口优化
217
                              .Text(string.IsNullOrWhiteSpace(e.PhoneNumber) ? "None" : e.PhoneNumber!);
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
                          table.Cell().BorderBottom(0.5f).BorderColor(Colors.Grey.Lighten2).Padding(5).Text(status);
                          table.Cell().BorderBottom(0.5f).BorderColor(Colors.Grey.Lighten2).Padding(5)
                              .Text(e.CreationTime.ToString("yyyy-MM-dd HH:mm"));
                      }
                  });
              });
          });
  
          var stream = new MemoryStream();
          document.GeneratePdf(stream);
          stream.Position = 0;
          return new FileStreamResult(stream, "application/pdf") { FileDownloadName = fileName };
      }
  
10fd1324   李曜臣   5-17接口优化
232
      private async Task<ISugarQueryable<FlPartnerDbEntity>> BuildPartnerListQueryAsync(PartnerGetListInputVo input)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
233
      {
10fd1324   李曜臣   5-17接口优化
234
235
          var scope = await PartnerScopeHelper.ResolvePartnerScopeAsync(CurrentUser, _dbContext);
  
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
236
237
          var keyword = input.Keyword?.Trim();
          var query = _dbContext.SqlSugarClient.Queryable<FlPartnerDbEntity>()
10fd1324   李曜臣   5-17接口优化
238
239
240
241
242
              .Where(x => !x.IsDeleted);
  
          query = PartnerScopeHelper.ApplyPartnerScope(query, scope);
  
          query = query
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
243
244
245
246
              .WhereIF(input.State != null, x => x.State == input.State)
              .WhereIF(!string.IsNullOrWhiteSpace(keyword),
                  x => x.PartnerName.Contains(keyword!) ||
                       (x.ContactEmail != null && x.ContactEmail.Contains(keyword!)) ||
10fd1324   李曜臣   5-17接口优化
247
248
249
250
251
252
                       (x.PhoneNumber != null && x.PhoneNumber.Contains(keyword!)) ||
                       (x.Street != null && x.Street.Contains(keyword!)) ||
                       (x.City != null && x.City.Contains(keyword!)) ||
                       (x.StateCode != null && x.StateCode.Contains(keyword!)) ||
                       (x.Country != null && x.Country.Contains(keyword!)) ||
                       (x.ZipCode != null && x.ZipCode.Contains(keyword!)));
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  
          if (!string.IsNullOrWhiteSpace(input.Sorting))
          {
              var sorting = input.Sorting.Trim();
              if (sorting.Equals("PartnerName desc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderByDescending(x => x.PartnerName);
              }
              else if (sorting.Equals("PartnerName asc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderBy(x => x.PartnerName);
              }
              else if (sorting.Equals("CreationTime desc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderByDescending(x => x.CreationTime);
              }
              else if (sorting.Equals("CreationTime asc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderBy(x => x.CreationTime);
              }
              else if (sorting.Equals("State desc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderByDescending(x => x.State);
              }
              else if (sorting.Equals("State asc", StringComparison.OrdinalIgnoreCase))
              {
                  query = query.OrderBy(x => x.State);
              }
              else
              {
                  query = query.OrderByDescending(x => x.CreationTime);
              }
          }
          else
          {
              query = query.OrderByDescending(x => x.CreationTime);
          }
  
          return query;
      }
  
10fd1324   李曜臣   5-17接口优化
294
      private static PartnerGetListOutputDto MapListItem(FlPartnerDbEntity x)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
295
      {
10fd1324   李曜臣   5-17接口优化
296
297
298
299
300
301
302
303
304
305
306
307
308
309
          var dto = new PartnerGetListOutputDto
          {
              Id = x.Id,
              PartnerName = x.PartnerName,
              ContactEmail = x.ContactEmail,
              PhoneNumber = x.PhoneNumber,
              State = x.State,
              CreationTime = x.CreationTime
          };
          MapAddressFields(dto, x);
          return dto;
      }
  
      private static PartnerGetOutputDto MapDetail(FlPartnerDbEntity x)
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
310
      {
10fd1324   李曜臣   5-17接口优化
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
          var dto = new PartnerGetOutputDto
          {
              Id = x.Id,
              PartnerName = x.PartnerName,
              ContactEmail = x.ContactEmail,
              PhoneNumber = x.PhoneNumber,
              State = x.State,
              CreationTime = x.CreationTime,
              LastModificationTime = x.LastModificationTime
          };
          MapAddressFields(dto, x);
          return dto;
      }
  
      private static void ApplyAddressFields(FlPartnerDbEntity entity, PartnerAddressFieldsDto input)
      {
          entity.Street = TrimToNull(input.Street);
          entity.City = TrimToNull(input.City);
          entity.StateCode = TrimToNull(input.StateCode);
          entity.Country = TrimToNull(input.Country);
          entity.ZipCode = TrimToNull(input.ZipCode);
      }
  
      private static void MapAddressFields(PartnerAddressFieldsDto dto, FlPartnerDbEntity entity)
      {
          dto.Street = entity.Street;
          dto.City = entity.City;
          dto.StateCode = entity.StateCode;
          dto.Country = entity.Country;
          dto.ZipCode = entity.ZipCode;
      }
  
      private static string? TrimToNull(string? value)
      {
          var t = value?.Trim();
          return string.IsNullOrEmpty(t) ? null : t;
      }
4d328ec2   李曜臣   平台端报表reports,仪表盘D...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
  
      private static bool IsPlausibleEmail(string email)
      {
          if (email.Length > 256)
          {
              return false;
          }
  
          var at = email.IndexOf('@');
          return at > 0 && at < email.Length - 1 && email.IndexOf('@', at + 1) < 0;
      }
  
      private static PagedResultWithPageDto<T> BuildPagedResult<T>(int skipCount, int maxResultCount, int total,
          List<T> items)
      {
          var pageSize = maxResultCount <= 0 ? items.Count : maxResultCount;
          var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(skipCount);
          var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
          return new PagedResultWithPageDto<T>
          {
              PageIndex = pageIndex,
              PageSize = pageSize,
              TotalCount = total,
              TotalPages = totalPages,
              Items = items
          };
      }
  }