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,11 +26,11 @@ public class ReportsLabelReportSummaryDto | ||
| 26 | /// <summary>相对上一同长周期变化率(百分比,如 20.1 表示 +20.1%)</summary> | 26 | /// <summary>相对上一同长周期变化率(百分比,如 20.1 表示 +20.1%)</summary> |
| 27 | public decimal TotalLabelsPrintedChangeRate { get; set; } | 27 | public decimal TotalLabelsPrintedChangeRate { get; set; } |
| 28 | 28 | ||
| 29 | - public string MostPrintedCategoryName { get; set; } = "无"; | 29 | + public string? MostPrintedCategoryName { get; set; } |
| 30 | 30 | ||
| 31 | public int MostPrintedCategoryCount { get; set; } | 31 | public int MostPrintedCategoryCount { get; set; } |
| 32 | 32 | ||
| 33 | - public string TopProductName { get; set; } = "无"; | 33 | + public string? TopProductName { get; set; } |
| 34 | 34 | ||
| 35 | public int TopProductCount { get; set; } | 35 | public int TopProductCount { get; set; } |
| 36 | 36 | ||
| @@ -43,9 +43,9 @@ public class ReportsLabelReportSummaryDto | @@ -43,9 +43,9 @@ public class ReportsLabelReportSummaryDto | ||
| 43 | 43 | ||
| 44 | public class ReportsCategoryCountDto | 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 | public int Count { get; set; } | 50 | public int Count { get; set; } |
| 51 | } | 51 | } |
| @@ -59,11 +59,11 @@ public class ReportsDailyCountDto | @@ -59,11 +59,11 @@ public class ReportsDailyCountDto | ||
| 59 | 59 | ||
| 60 | public class ReportsTopProductRowDto | 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 | public int TotalPrinted { get; set; } | 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,8 +368,8 @@ public class ReportsAppService : ApplicationService, IReportsAppService | ||
| 368 | .OrderByDescending(x => x.Cnt) | 368 | .OrderByDescending(x => x.Cnt) |
| 369 | .Select(x => new ReportsCategoryCountDto | 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 | Count = x.Cnt | 373 | Count = x.Cnt |
| 374 | }) | 374 | }) |
| 375 | .ToList(); | 375 | .ToList(); |
| @@ -379,9 +379,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService | @@ -379,9 +379,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService | ||
| 379 | var pct = totalCur <= 0 ? 0m : Math.Round(x.Cnt * 100m / totalCur, 2); | 379 | var pct = totalCur <= 0 ? 0m : Math.Round(x.Cnt * 100m / totalCur, 2); |
| 380 | return new ReportsTopProductRowDto | 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 | TotalPrinted = x.Cnt, | 385 | TotalPrinted = x.Cnt, |
| 386 | UsagePercent = pct | 386 | UsagePercent = pct |
| 387 | }; | 387 | }; |
| @@ -394,9 +394,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService | @@ -394,9 +394,9 @@ public class ReportsAppService : ApplicationService, IReportsAppService | ||
| 394 | TotalLabelsPrinted = totalCur, | 394 | TotalLabelsPrinted = totalCur, |
| 395 | TotalLabelsPrintedPrevPeriod = totalPrev, | 395 | TotalLabelsPrintedPrevPeriod = totalPrev, |
| 396 | TotalLabelsPrintedChangeRate = CalcChangeRate(totalCur, totalPrev), | 396 | TotalLabelsPrintedChangeRate = CalcChangeRate(totalCur, totalPrev), |
| 397 | - MostPrintedCategoryName = topCat is null ? "无" : (topCat.CategoryName?.Trim() ?? "无"), | 397 | + MostPrintedCategoryName = string.IsNullOrWhiteSpace(topCat?.CategoryName) ? null : topCat.CategoryName.Trim(), |
| 398 | MostPrintedCategoryCount = topCat?.Cnt ?? 0, | 398 | MostPrintedCategoryCount = topCat?.Cnt ?? 0, |
| 399 | - TopProductName = topProd is null ? "无" : (topProd.ProductName?.Trim() ?? "无"), | 399 | + TopProductName = string.IsNullOrWhiteSpace(topProd?.ProductName) ? null : topProd.ProductName.Trim(), |
| 400 | TopProductCount = topProd?.Cnt ?? 0, | 400 | TopProductCount = topProd?.Cnt ?? 0, |
| 401 | AvgDailyPrints = avgDaily, | 401 | AvgDailyPrints = avgDaily, |
| 402 | AvgDailyPrintsPrevPeriod = avgDailyPrev, | 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,11 +214,14 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService | ||
| 214 | throw new UserFriendlyException("用户不存在或已停用"); | 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 | var roleNames = roleRows.Select(x => x.RoleName?.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); | 226 | var roleNames = roleRows.Select(x => x.RoleName?.Trim()).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); |
| 224 | var roleDisplay = roleNames.Count == 0 ? "无" : string.Join(", ", roleNames); | 227 | var roleDisplay = roleNames.Count == 0 ? "无" : string.Join(", ", roleNames); |
| @@ -338,22 +341,19 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService | @@ -338,22 +341,19 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService | ||
| 338 | return ("无", "无"); | 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 | var row = rows.FirstOrDefault(); | 358 | var row = rows.FirstOrDefault(); |
| 359 | if (row is null) | 359 | if (row is null) |
| @@ -520,4 +520,22 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService | @@ -520,4 +520,22 @@ public class UsAppAuthAppService : ApplicationService, IUsAppAuthAppService | ||
| 520 | 520 | ||
| 521 | return segments.Count == 0 ? "无" : string.Join(", ", segments); | 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,19 +233,19 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... | ||
| 233 | ### HTTP | 233 | ### HTTP |
| 234 | 234 | ||
| 235 | - **方法**:`GET` | 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 | - **鉴权**:需要登录(`Authorization: Bearer {token}`) | 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 | ```http | 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 | Host: localhost:19001 | 249 | Host: localhost:19001 |
| 250 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... | 250 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... |
| 251 | ``` | 251 | ``` |