Commit 3ff23c2097c63c76eb0172ca818a1ff17aded278
1 parent
4d328ec2
修复app端:我的资料,门店信息
修复平台端:仪表盘统计
Showing
4 changed files
with
56 additions
and
38 deletions
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Reports/ReportsLabelReportOutputDto.cs
| ... | ... | @@ -26,11 +26,11 @@ public class ReportsLabelReportSummaryDto |
| 26 | 26 | /// <summary>相对上一同长周期变化率(百分比,如 20.1 表示 +20.1%)</summary> |
| 27 | 27 | public decimal TotalLabelsPrintedChangeRate { get; set; } |
| 28 | 28 | |
| 29 | - public string MostPrintedCategoryName { get; set; } = "无"; | |
| 29 | + public string? MostPrintedCategoryName { get; set; } | |
| 30 | 30 | |
| 31 | 31 | public int MostPrintedCategoryCount { get; set; } |
| 32 | 32 | |
| 33 | - public string TopProductName { get; set; } = "无"; | |
| 33 | + public string? TopProductName { get; set; } | |
| 34 | 34 | |
| 35 | 35 | public int TopProductCount { get; set; } |
| 36 | 36 | |
| ... | ... | @@ -43,9 +43,9 @@ public class ReportsLabelReportSummaryDto |
| 43 | 43 | |
| 44 | 44 | public class ReportsCategoryCountDto |
| 45 | 45 | { |
| 46 | - public string CategoryId { get; set; } = string.Empty; | |
| 46 | + public string? CategoryId { get; set; } | |
| 47 | 47 | |
| 48 | - public string CategoryName { get; set; } = "无"; | |
| 48 | + public string? CategoryName { get; set; } | |
| 49 | 49 | |
| 50 | 50 | public int Count { get; set; } |
| 51 | 51 | } |
| ... | ... | @@ -59,11 +59,11 @@ public class ReportsDailyCountDto |
| 59 | 59 | |
| 60 | 60 | public class ReportsTopProductRowDto |
| 61 | 61 | { |
| 62 | - public string ProductId { get; set; } = string.Empty; | |
| 62 | + public string? ProductId { get; set; } | |
| 63 | 63 | |
| 64 | - public string ProductName { get; set; } = "无"; | |
| 64 | + public string? ProductName { get; set; } | |
| 65 | 65 | |
| 66 | - public string CategoryName { get; set; } = "无"; | |
| 66 | + public string? CategoryName { get; set; } | |
| 67 | 67 | |
| 68 | 68 | public int TotalPrinted { get; set; } |
| 69 | 69 | ... | ... |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/ReportsAppService.cs
| ... | ... | @@ -368,8 +368,8 @@ public class ReportsAppService : ApplicationService, IReportsAppService |
| 368 | 368 | .OrderByDescending(x => x.Cnt) |
| 369 | 369 | .Select(x => new ReportsCategoryCountDto |
| 370 | 370 | { |
| 371 | - CategoryId = x.Id ?? string.Empty, | |
| 372 | - CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? "无" : x.CategoryName.Trim(), | |
| 371 | + CategoryId = string.IsNullOrWhiteSpace(x.Id) ? null : x.Id.Trim(), | |
| 372 | + CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? null : x.CategoryName.Trim(), | |
| 373 | 373 | Count = x.Cnt |
| 374 | 374 | }) |
| 375 | 375 | .ToList(); |
| ... | ... | @@ -379,9 +379,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService |
| 379 | 379 | var pct = totalCur <= 0 ? 0m : Math.Round(x.Cnt * 100m / totalCur, 2); |
| 380 | 380 | return new ReportsTopProductRowDto |
| 381 | 381 | { |
| 382 | - ProductId = x.Id ?? string.Empty, | |
| 383 | - ProductName = string.IsNullOrWhiteSpace(x.ProductName) ? "无" : x.ProductName.Trim(), | |
| 384 | - CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? "无" : x.CategoryName!.Trim(), | |
| 382 | + ProductId = string.IsNullOrWhiteSpace(x.Id) ? null : x.Id.Trim(), | |
| 383 | + ProductName = string.IsNullOrWhiteSpace(x.ProductName) ? null : x.ProductName.Trim(), | |
| 384 | + CategoryName = string.IsNullOrWhiteSpace(x.CategoryName) ? null : x.CategoryName!.Trim(), | |
| 385 | 385 | TotalPrinted = x.Cnt, |
| 386 | 386 | UsagePercent = pct |
| 387 | 387 | }; |
| ... | ... | @@ -394,9 +394,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService |
| 394 | 394 | TotalLabelsPrinted = totalCur, |
| 395 | 395 | TotalLabelsPrintedPrevPeriod = totalPrev, |
| 396 | 396 | TotalLabelsPrintedChangeRate = CalcChangeRate(totalCur, totalPrev), |
| 397 | - MostPrintedCategoryName = topCat is null ? "无" : (topCat.CategoryName?.Trim() ?? "无"), | |
| 397 | + MostPrintedCategoryName = string.IsNullOrWhiteSpace(topCat?.CategoryName) ? null : topCat.CategoryName.Trim(), | |
| 398 | 398 | MostPrintedCategoryCount = topCat?.Cnt ?? 0, |
| 399 | - TopProductName = topProd is null ? "无" : (topProd.ProductName?.Trim() ?? "无"), | |
| 399 | + TopProductName = string.IsNullOrWhiteSpace(topProd?.ProductName) ? null : topProd.ProductName.Trim(), | |
| 400 | 400 | TopProductCount = topProd?.Cnt ?? 0, |
| 401 | 401 | AvgDailyPrints = avgDaily, |
| 402 | 402 | AvgDailyPrintsPrevPeriod = avgDailyPrev, | ... | ... |
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/UsAppAuthAppService.cs
| ... | ... | @@ -214,11 +214,14 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService |
| 214 | 214 | throw new UserFriendlyException("用户不存在或已停用"); |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | - var roleRows = await _dbContext.SqlSugarClient.Queryable<UserRoleEntity, RoleAggregateRoot>((ur, r) => ur.RoleId == r.Id) | |
| 218 | - .Where((ur, r) => ur.UserId == userId && !r.IsDeleted && r.State) | |
| 219 | - .OrderBy((ur, r) => r.OrderNum) | |
| 220 | - .Select((ur, r) => new { r.RoleName, r.RoleCode }) | |
| 221 | - .ToListAsync(); | |
| 217 | + // 避免 SqlSugar 在该环境下对 Role 关联表达式解析异常(Select 不支持),这里改用显式 SQL 查询角色。 | |
| 218 | + var roleRows = await _dbContext.SqlSugarClient.Ado.SqlQueryAsync<MyProfileRoleRow>( | |
| 219 | + @"SELECT r.RoleName, r.RoleCode | |
| 220 | + FROM UserRole ur | |
| 221 | + INNER JOIN Role r ON ur.RoleId = r.Id | |
| 222 | + WHERE ur.UserId = @UserId AND r.IsDeleted = 0 AND r.State = 1 | |
| 223 | + ORDER BY r.OrderNum ASC", | |
| 224 | + new { UserId = userId }); | |
| 222 | 225 | |
| 223 | 226 | var roleNames = roleRows.Select(x => x.RoleName?.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); |
| 224 | 227 | var roleDisplay = roleNames.Count == 0 ? "无" : string.Join(", ", roleNames); |
| ... | ... | @@ -338,22 +341,19 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService |
| 338 | 341 | return ("无", "无"); |
| 339 | 342 | } |
| 340 | 343 | |
| 341 | - var rows = await _dbContext.SqlSugarClient.Queryable<UserAggregateRoot, UserRoleEntity, RoleAggregateRoot>( | |
| 342 | - (u, ur, r) => u.Id == ur.UserId && ur.RoleId == r.Id) | |
| 343 | - .Where((u, ur, r) => userGuids.Contains(u.Id) && !u.IsDeleted && u.State) | |
| 344 | - .Where((u, ur, r) => !r.IsDeleted && r.State) | |
| 345 | - .Where((u, ur, r) => | |
| 346 | - SqlFunc.ToLower(r.RoleCode).Contains("manager") || | |
| 347 | - SqlFunc.ToLower(r.RoleName).Contains("manager")) | |
| 348 | - .OrderBy((u, ur, r) => u.Name) | |
| 349 | - .Select((u, ur, r) => new | |
| 350 | - { | |
| 351 | - u.Name, | |
| 352 | - u.Nick, | |
| 353 | - u.UserName, | |
| 354 | - u.Phone | |
| 355 | - }) | |
| 356 | - .ToListAsync(); | |
| 344 | + var rows = await _dbContext.SqlSugarClient.Ado.SqlQueryAsync<LocationManagerRow>( | |
| 345 | + @"SELECT u.Name, u.Nick, u.UserName, u.Phone | |
| 346 | + FROM User u | |
| 347 | + INNER JOIN UserRole ur ON u.Id = ur.UserId | |
| 348 | + INNER JOIN Role r ON ur.RoleId = r.Id | |
| 349 | + WHERE u.IsDeleted = 0 | |
| 350 | + AND u.State = 1 | |
| 351 | + AND r.IsDeleted = 0 | |
| 352 | + AND r.State = 1 | |
| 353 | + AND (LOWER(r.RoleCode) LIKE '%manager%' OR LOWER(r.RoleName) LIKE '%manager%') | |
| 354 | + AND u.Id IN (@UserIds) | |
| 355 | + ORDER BY u.Name ASC", | |
| 356 | + new { UserIds = userGuids }); | |
| 357 | 357 | |
| 358 | 358 | var row = rows.FirstOrDefault(); |
| 359 | 359 | if (row is null) |
| ... | ... | @@ -520,4 +520,22 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService |
| 520 | 520 | |
| 521 | 521 | return segments.Count == 0 ? "无" : string.Join(", ", segments); |
| 522 | 522 | } |
| 523 | + | |
| 524 | + private sealed class MyProfileRoleRow | |
| 525 | + { | |
| 526 | + public string? RoleName { get; set; } | |
| 527 | + | |
| 528 | + public string? RoleCode { get; set; } | |
| 529 | + } | |
| 530 | + | |
| 531 | + private sealed class LocationManagerRow | |
| 532 | + { | |
| 533 | + public string? Name { get; set; } | |
| 534 | + | |
| 535 | + public string? Nick { get; set; } | |
| 536 | + | |
| 537 | + public string? UserName { get; set; } | |
| 538 | + | |
| 539 | + public long? Phone { get; set; } | |
| 540 | + } | |
| 523 | 541 | } | ... | ... |
项目相关文档/美国版App登录接口说明.md
| ... | ... | @@ -233,19 +233,19 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
| 233 | 233 | ### HTTP |
| 234 | 234 | |
| 235 | 235 | - **方法**:`GET` |
| 236 | -- **路径**:`/api/app/us-app-auth/location-detail`(以 Swagger 中 `UsAppAuth` → `GetLocationDetail` 为准;`locationId` 一般为 **Query** 参数) | |
| 236 | +- **路径**:`/api/app/us-app-auth/location-detail/{locationId}`(以 Swagger 中 `UsAppAuth` → `GetLocationDetail` 为准) | |
| 237 | 237 | - **鉴权**:需要登录(`Authorization: Bearer {token}`) |
| 238 | 238 | |
| 239 | 239 | ### 请求参数 |
| 240 | 240 | |
| 241 | 241 | | 参数名 | 位置 | 类型 | 必填 | 说明 | |
| 242 | 242 | |--------|------|------|------|------| |
| 243 | -| `locationId` | Query | string | 是 | 门店主键,Guid 字符串(与 `locations[].id` 一致) | | |
| 243 | +| `locationId` | Path | string | 是 | 门店主键,Guid 字符串(与 `locations[].id` 一致) | | |
| 244 | 244 | |
| 245 | 245 | ### 传参示例 |
| 246 | 246 | |
| 247 | 247 | ```http |
| 248 | -GET /api/app/us-app-auth/location-detail?locationId=a2696b9e-2277-11f1-b4c6-00163e0c7c4f HTTP/1.1 | |
| 248 | +GET /api/app/us-app-auth/location-detail/a2696b9e-2277-11f1-b4c6-00163e0c7c4f HTTP/1.1 | |
| 249 | 249 | Host: localhost:19001 |
| 250 | 250 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
| 251 | 251 | ``` | ... | ... |