From 9df65e38a558fdc836d119536fd9a1f6bdd6ed51 Mon Sep 17 00:00:00 2001 From: 李曜臣 Date: Wed, 18 Mar 2026 16:34:04 +0800 Subject: [PATCH] 实现美国版门店与RBAC对外接口 --- 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs | 34 ++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs | 39 +++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs | 30 ++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs | 38 ++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs | 40 ++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs | 26 ++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs | 19 +++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs | 24 ++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs | 9 +++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs | 23 +++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs | 25 +++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs | 22 ++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs | 9 +++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs | 9 +++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs | 16 ++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs | 22 ++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj | 1 + 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs | 38 ++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs | 38 ++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs | 38 ++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs | 26 ++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj | 1 + 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 项目相关文档/门店(Location)接口对接说明.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 28 files changed, 1446 insertions(+), 0 deletions(-) create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs create mode 100644 美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs create mode 100644 项目相关文档/门店(Location)接口对接说明.md diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs new file mode 100644 index 0000000..64daa2c --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs @@ -0,0 +1,34 @@ +namespace FoodLabeling.Application.Contracts.Dtos.Common; + +/// +/// 分页返回(包含当前页、总页数) +/// +/// 列表项类型 +public class PagedResultWithPageDto +{ + /// + /// 当前页码(从 1 开始) + /// + public int PageIndex { get; set; } + + /// + /// 每页条数 + /// + public int PageSize { get; set; } + + /// + /// 总条数 + /// + public long TotalCount { get; set; } + + /// + /// 总页数 + /// + public int TotalPages { get; set; } + + /// + /// 列表数据 + /// + public List Items { get; set; } = new(); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs new file mode 100644 index 0000000..bf453f5 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs @@ -0,0 +1,39 @@ +namespace FoodLabeling.Application.Contracts.Dtos.Location; + +/// +/// 新增门店入参 +/// +public class LocationCreateInputVo +{ + public string? Partner { get; set; } + + public string? GroupName { get; set; } + + /// + /// Location ID(业务编码) + /// + public string LocationCode { get; set; } = string.Empty; + + public string LocationName { get; set; } = string.Empty; + + public string? Street { get; set; } + + public string? City { get; set; } + + public string? StateCode { get; set; } + + public string? Country { get; set; } + + public string? ZipCode { get; set; } + + public string? Phone { get; set; } + + public string? Email { get; set; } + + public decimal? Latitude { get; set; } + + public decimal? Longitude { get; set; } + + public bool State { get; set; } = true; +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs new file mode 100644 index 0000000..1413502 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs @@ -0,0 +1,30 @@ +using Volo.Abp.Application.Dtos; + +namespace FoodLabeling.Application.Contracts.Dtos.Location; + +/// +/// 门店分页查询入参 +/// +public class LocationGetListInputVo : PagedAndSortedResultRequestDto +{ + /// + /// 模糊搜索(Location ID/Name/Street/City/State/Country/Zip/Phone/Email) + /// + public string? Keyword { get; set; } + + /// + /// Partner + /// + public string? Partner { get; set; } + + /// + /// Group + /// + public string? GroupName { get; set; } + + /// + /// 启用状态 + /// + public bool? State { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs new file mode 100644 index 0000000..067aec1 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs @@ -0,0 +1,38 @@ +namespace FoodLabeling.Application.Contracts.Dtos.Location; + +/// +/// 门店列表输出 +/// +public class LocationGetListOutputDto +{ + public Guid Id { get; set; } + + public string? Partner { get; set; } + + public string? GroupName { get; set; } + + public string LocationCode { get; set; } = string.Empty; + + public string LocationName { get; set; } = string.Empty; + + public string? Street { get; set; } + + public string? City { get; set; } + + public string? StateCode { get; set; } + + public string? Country { get; set; } + + public string? ZipCode { get; set; } + + public string? Phone { get; set; } + + public string? Email { get; set; } + + public decimal? Latitude { get; set; } + + public decimal? Longitude { get; set; } + + public bool State { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs new file mode 100644 index 0000000..45f7731 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs @@ -0,0 +1,40 @@ +namespace FoodLabeling.Application.Contracts.Dtos.Location; + +/// +/// 编辑门店入参 +/// +public class LocationUpdateInputVo +{ + public string? Partner { get; set; } + + public string? GroupName { get; set; } + + /// + /// Location Name + /// + public string LocationName { get; set; } = string.Empty; + + public string? Street { get; set; } + + public string? City { get; set; } + + public string? StateCode { get; set; } + + public string? Country { get; set; } + + public string? ZipCode { get; set; } + + public string? Phone { get; set; } + + public string? Email { get; set; } + + public decimal? Latitude { get; set; } + + public decimal? Longitude { get; set; } + + /// + /// 启用状态 + /// + public bool State { get; set; } = true; +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs new file mode 100644 index 0000000..ee5d658 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs @@ -0,0 +1,26 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; + +/// +/// 新增权限(Menu)入参(美国版对外) +/// +public class RbacMenuCreateInputVo +{ + public string MenuName { get; set; } = string.Empty; + + public Guid ParentId { get; set; } + + public int MenuType { get; set; } + + public int MenuSource { get; set; } + + public string? PermissionCode { get; set; } + + public string? Router { get; set; } + + public string? Component { get; set; } + + public int OrderNum { get; set; } = 0; + + public bool State { get; set; } = true; +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs new file mode 100644 index 0000000..785f12b --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs @@ -0,0 +1,19 @@ +using Volo.Abp.Application.Dtos; + +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; + +/// +/// 权限(Menu)分页查询入参(美国版对外) +/// +public class RbacMenuGetListInputVo : PagedAndSortedResultRequestDto +{ + public string? MenuName { get; set; } + + public bool? State { get; set; } + + /// + /// 菜单来源(与 rbac 的 MenuSource 含义一致,int 存储) + /// + public int? MenuSource { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs new file mode 100644 index 0000000..6970d00 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs @@ -0,0 +1,24 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; + +/// +/// 权限(Menu)列表输出(美国版对外) +/// +public class RbacMenuGetListOutputDto +{ + public Guid Id { get; set; } + + public Guid ParentId { get; set; } + + public string MenuName { get; set; } = string.Empty; + + public string? PermissionCode { get; set; } + + public int MenuType { get; set; } + + public int MenuSource { get; set; } + + public int OrderNum { get; set; } + + public bool State { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs new file mode 100644 index 0000000..a592d89 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs @@ -0,0 +1,9 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu; + +/// +/// 编辑权限(Menu)入参(美国版对外) +/// +public class RbacMenuUpdateInputVo : RbacMenuCreateInputVo +{ +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs new file mode 100644 index 0000000..53b2e73 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs @@ -0,0 +1,23 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole; + +/// +/// 新增角色入参(美国版对外) +/// +public class RbacRoleCreateInputVo +{ + public string RoleName { get; set; } = string.Empty; + + public string RoleCode { get; set; } = string.Empty; + + public string? Remark { get; set; } + + /// + /// 数据范围(与 rbac 的 DataScope 含义一致,int 存储) + /// + public int DataScope { get; set; } = 0; + + public bool State { get; set; } = true; + + public int OrderNum { get; set; } = 0; +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs new file mode 100644 index 0000000..02deeb7 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs @@ -0,0 +1,25 @@ +using Volo.Abp.Application.Dtos; + +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole; + +/// +/// 角色分页查询入参(美国版对外) +/// +public class RbacRoleGetListInputVo : PagedAndSortedResultRequestDto +{ + /// + /// 角色名称(模糊) + /// + public string? RoleName { get; set; } + + /// + /// 角色编码(模糊) + /// + public string? RoleCode { get; set; } + + /// + /// 启用状态 + /// + public bool? State { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs new file mode 100644 index 0000000..3940df9 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs @@ -0,0 +1,22 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole; + +/// +/// 角色列表输出(美国版对外) +/// +public class RbacRoleGetListOutputDto +{ + public Guid Id { get; set; } + + public string RoleName { get; set; } = string.Empty; + + public string RoleCode { get; set; } = string.Empty; + + public string? Remark { get; set; } + + public int DataScope { get; set; } + + public bool State { get; set; } + + public int OrderNum { get; set; } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs new file mode 100644 index 0000000..877e1b0 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs @@ -0,0 +1,9 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole; + +/// +/// 角色详情输出(美国版对外) +/// +public class RbacRoleGetOutputDto : RbacRoleGetListOutputDto +{ +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs new file mode 100644 index 0000000..680ee9c --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs @@ -0,0 +1,9 @@ +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole; + +/// +/// 编辑角色入参(美国版对外) +/// +public class RbacRoleUpdateInputVo : RbacRoleCreateInputVo +{ +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs new file mode 100644 index 0000000..19e588d --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu; + +/// +/// 角色-权限移除入参 +/// +public class RbacRoleMenuRemoveInputVo +{ + [Required] + public Guid RoleId { get; set; } + + [Required] + public List MenuIds { get; set; } = new(); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs new file mode 100644 index 0000000..705da63 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; + +namespace FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu; + +/// +/// 角色-权限设置入参(覆盖式) +/// +public class RbacRoleMenuSetInputVo +{ + /// + /// 角色ID + /// + [Required] + public Guid RoleId { get; set; } + + /// + /// 菜单ID列表(覆盖式) + /// + [Required] + public List MenuIds { get; set; } = new(); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj index 9e3e3bd..6a5eb2d 100644 --- a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj @@ -4,6 +4,7 @@ + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs new file mode 100644 index 0000000..4474374 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs @@ -0,0 +1,38 @@ +using FoodLabeling.Application.Contracts.Dtos.Location; +using FoodLabeling.Application.Contracts.Dtos.Common; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace FoodLabeling.Application.Contracts.IServices; + +/// +/// 门店管理接口(美国版) +/// +public interface ILocationAppService : IApplicationService +{ + /// + /// 门店分页列表 + /// + /// 查询条件 + Task> GetListAsync(LocationGetListInputVo input); + + /// + /// 新增门店 + /// + /// 门店信息 + Task CreateAsync(LocationCreateInputVo input); + + /// + /// 编辑门店 + /// + /// 门店Id + /// 门店信息 + Task UpdateAsync(Guid id, LocationUpdateInputVo input); + + /// + /// 删除门店(逻辑删除) + /// + /// 门店Id + Task DeleteAsync(Guid id); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs new file mode 100644 index 0000000..2eba979 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs @@ -0,0 +1,38 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacMenu; +using FoodLabeling.Application.Contracts.Dtos.Common; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace FoodLabeling.Application.Contracts.IServices; + +/// +/// 权限(Menu)管理接口(仅用于食品标签-美国版对外) +/// +public interface IRbacMenuAppService : IApplicationService +{ + /// + /// 权限分页列表 + /// + Task> GetListAsync(RbacMenuGetListInputVo input); + + /// + /// 权限详情 + /// + Task GetAsync(Guid id); + + /// + /// 新增权限 + /// + Task CreateAsync(RbacMenuCreateInputVo input); + + /// + /// 编辑权限 + /// + Task UpdateAsync(Guid id, RbacMenuUpdateInputVo input); + + /// + /// 删除权限(逻辑删除) + /// + Task DeleteAsync(List ids); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs new file mode 100644 index 0000000..48a527c --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs @@ -0,0 +1,38 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacRole; +using FoodLabeling.Application.Contracts.Dtos.Common; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace FoodLabeling.Application.Contracts.IServices; + +/// +/// 角色管理接口(仅用于食品标签-美国版对外) +/// +public interface IRbacRoleAppService : IApplicationService +{ + /// + /// 角色分页列表 + /// + Task> GetListAsync(RbacRoleGetListInputVo input); + + /// + /// 角色详情 + /// + Task GetAsync(Guid id); + + /// + /// 新增角色 + /// + Task CreateAsync(RbacRoleCreateInputVo input); + + /// + /// 编辑角色 + /// + Task UpdateAsync(Guid id, RbacRoleUpdateInputVo input); + + /// + /// 删除角色(逻辑删除) + /// + Task DeleteAsync(List ids); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs new file mode 100644 index 0000000..1a6cda5 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs @@ -0,0 +1,26 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu; +using Volo.Abp.Application.Services; + +namespace FoodLabeling.Application.Contracts.IServices; + +/// +/// 角色-权限关联接口(仅用于食品标签-美国版对外) +/// +public interface IRbacRoleMenuAppService : IApplicationService +{ + /// + /// 覆盖式设置角色的菜单权限 + /// + Task SetAsync(RbacRoleMenuSetInputVo input); + + /// + /// 获取角色已分配的菜单ID列表 + /// + Task> GetMenuIdsAsync(Guid roleId); + + /// + /// 移除角色的指定菜单权限 + /// + Task RemoveAsync(RbacRoleMenuRemoveInputVo input); +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj index 67daccd..5133544 100644 --- a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj @@ -5,6 +5,7 @@ + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs new file mode 100644 index 0000000..3b6924e --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs @@ -0,0 +1,224 @@ +using FoodLabeling.Application.Contracts.Dtos.Location; +using FoodLabeling.Application.Contracts.IServices; +using FoodLabeling.Domain.Entities; +using FoodLabeling.Application.Contracts.Dtos.Common; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace FoodLabeling.Application.Services; + +/// +/// 门店管理服务(美国版) +/// +public class LocationAppService : ApplicationService, ILocationAppService +{ + private readonly ISqlSugarRepository _locationRepository; + + public LocationAppService(ISqlSugarRepository locationRepository) + { + _locationRepository = locationRepository; + } + + /// + public async Task> GetListAsync([FromQuery] LocationGetListInputVo input) + { + RefAsync total = 0; + + var keyword = input.Keyword?.Trim(); + var partner = input.Partner?.Trim(); + var groupName = input.GroupName?.Trim(); + + var query = _locationRepository._DbQueryable + .Where(x => x.IsDeleted == false) + .WhereIF(!string.IsNullOrEmpty(partner), x => x.Partner == partner) + .WhereIF(!string.IsNullOrEmpty(groupName), x => x.GroupName == groupName) + .WhereIF(input.State is not null, x => x.State == input.State) + .WhereIF(!string.IsNullOrEmpty(keyword), + x => + x.LocationCode.Contains(keyword!) || + x.LocationName.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!)) || + (x.Phone != null && x.Phone.Contains(keyword!)) || + (x.Email != null && x.Email.Contains(keyword!)) + ); + + // 先按排序字段走(如前端传入),否则默认按创建时间倒序 + if (!string.IsNullOrWhiteSpace(input.Sorting)) + { + query = query.OrderBy(input.Sorting); + } + else + { + query = query.OrderBy(x => x.CreationTime, OrderByType.Desc); + } + + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); + + var items = entities.Select(x => new LocationGetListOutputDto + { + Id = x.Id, + Partner = x.Partner, + GroupName = x.GroupName, + LocationCode = x.LocationCode, + LocationName = x.LocationName, + Street = x.Street, + City = x.City, + StateCode = x.StateCode, + Country = x.Country, + ZipCode = x.ZipCode, + Phone = x.Phone, + Email = x.Email, + Latitude = x.Latitude, + Longitude = x.Longitude, + State = x.State + }).ToList(); + + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount; + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1; + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize); + + return new PagedResultWithPageDto + { + PageIndex = pageIndex, + PageSize = pageSize, + TotalCount = total, + TotalPages = totalPages, + Items = items + }; + } + + /// + public async Task CreateAsync([FromBody] LocationCreateInputVo input) + { + var locationCode = input.LocationCode?.Trim(); + if (string.IsNullOrWhiteSpace(locationCode)) + { + throw new UserFriendlyException("Location ID不能为空"); + } + + var locationName = input.LocationName?.Trim(); + if (string.IsNullOrWhiteSpace(locationName)) + { + throw new UserFriendlyException("Location Name不能为空"); + } + + var isExist = await _locationRepository.IsAnyAsync(x => x.LocationCode == locationCode); + if (isExist) + { + throw new UserFriendlyException("Location ID已存在"); + } + + var entity = new LocationAggregateRoot(GuidGenerator.Create()) + { + Partner = input.Partner?.Trim(), + GroupName = input.GroupName?.Trim(), + LocationCode = locationCode, + LocationName = locationName, + Street = input.Street?.Trim(), + City = input.City?.Trim(), + StateCode = input.StateCode?.Trim(), + Country = input.Country?.Trim(), + ZipCode = input.ZipCode?.Trim(), + Phone = input.Phone?.Trim(), + Email = input.Email?.Trim(), + Latitude = input.Latitude, + Longitude = input.Longitude, + State = input.State + }; + + await _locationRepository.InsertAsync(entity); + + return new LocationGetListOutputDto + { + Id = entity.Id, + Partner = entity.Partner, + GroupName = entity.GroupName, + LocationCode = entity.LocationCode, + LocationName = entity.LocationName, + Street = entity.Street, + City = entity.City, + StateCode = entity.StateCode, + Country = entity.Country, + ZipCode = entity.ZipCode, + Phone = entity.Phone, + Email = entity.Email, + Latitude = entity.Latitude, + Longitude = entity.Longitude, + State = entity.State + }; + } + + /// + public async Task UpdateAsync(Guid id, [FromBody] LocationUpdateInputVo input) + { + var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("门店不存在"); + } + + var locationName = input.LocationName?.Trim(); + if (string.IsNullOrWhiteSpace(locationName)) + { + throw new UserFriendlyException("Location Name不能为空"); + } + + // LocationCode 默认不允许修改:业务编码需要保持唯一且稳定(如需变更,应走“新建+迁移”方案) + entity.Partner = input.Partner?.Trim(); + entity.GroupName = input.GroupName?.Trim(); + entity.LocationName = locationName; + entity.Street = input.Street?.Trim(); + entity.City = input.City?.Trim(); + entity.StateCode = input.StateCode?.Trim(); + entity.Country = input.Country?.Trim(); + entity.ZipCode = input.ZipCode?.Trim(); + entity.Phone = input.Phone?.Trim(); + entity.Email = input.Email?.Trim(); + entity.Latitude = input.Latitude; + entity.Longitude = input.Longitude; + entity.State = input.State; + + await _locationRepository.UpdateAsync(entity); + + return new LocationGetListOutputDto + { + Id = entity.Id, + Partner = entity.Partner, + GroupName = entity.GroupName, + LocationCode = entity.LocationCode, + LocationName = entity.LocationName, + Street = entity.Street, + City = entity.City, + StateCode = entity.StateCode, + Country = entity.Country, + ZipCode = entity.ZipCode, + Phone = entity.Phone, + Email = entity.Email, + Latitude = entity.Latitude, + Longitude = entity.Longitude, + State = entity.State + }; + } + + /// + public async Task DeleteAsync(Guid id) + { + var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("门店不存在"); + } + + entity.IsDeleted = true; + await _locationRepository.UpdateAsync(entity); + } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs new file mode 100644 index 0000000..f4f8a4a --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs @@ -0,0 +1,157 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacMenu; +using FoodLabeling.Application.Contracts.Dtos.Common; +using FoodLabeling.Application.Contracts.IServices; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Entities; +using Yi.Framework.Rbac.Domain.Entities; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace FoodLabeling.Application.Services; + +/// +/// 权限(Menu)管理(食品标签-美国版对外) +/// +public class RbacMenuAppService : ApplicationService, IRbacMenuAppService +{ + private readonly ISqlSugarRepository _menuRepository; + + public RbacMenuAppService(ISqlSugarRepository menuRepository) + { + _menuRepository = menuRepository; + } + + /// + public async Task> GetListAsync([FromQuery] RbacMenuGetListInputVo input) + { + RefAsync total = 0; + + var query = _menuRepository._DbQueryable + .Where(x => x.IsDeleted == false) + .WhereIF(!string.IsNullOrWhiteSpace(input.MenuName), x => x.MenuName.Contains(input.MenuName!.Trim())) + .WhereIF(input.State is not null, x => x.State == input.State) + .WhereIF(input.MenuSource is not null, x => x.MenuSource == (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource!.Value) + .OrderBy(x => x.OrderNum, OrderByType.Desc); + + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); + + var items = entities.Select(x => new RbacMenuGetListOutputDto + { + Id = x.Id, + ParentId = x.ParentId, + MenuName = x.MenuName ?? string.Empty, + PermissionCode = x.PermissionCode, + MenuType = (int)x.MenuType, + MenuSource = (int)x.MenuSource, + OrderNum = x.OrderNum, + State = x.State + }).ToList(); + + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount; + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1; + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize); + + return new PagedResultWithPageDto + { + PageIndex = pageIndex, + PageSize = pageSize, + TotalCount = total, + TotalPages = totalPages, + Items = items + }; + } + + /// + public async Task GetAsync(Guid id) + { + var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("权限不存在"); + } + + return new RbacMenuGetListOutputDto + { + Id = entity.Id, + ParentId = entity.ParentId, + MenuName = entity.MenuName ?? string.Empty, + PermissionCode = entity.PermissionCode, + MenuType = (int)entity.MenuType, + MenuSource = (int)entity.MenuSource, + OrderNum = entity.OrderNum, + State = entity.State + }; + } + + /// + public async Task CreateAsync([FromBody] RbacMenuCreateInputVo input) + { + var name = input.MenuName?.Trim(); + if (string.IsNullOrWhiteSpace(name)) + { + throw new UserFriendlyException("权限名称不能为空"); + } + + var entity = new MenuAggregateRoot + { + MenuName = name, + ParentId = input.ParentId, + MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType, + MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource, + PermissionCode = input.PermissionCode?.Trim(), + Router = input.Router?.Trim(), + Component = input.Component?.Trim(), + OrderNum = input.OrderNum, + State = input.State + }; + EntityHelper.TrySetId(entity, () => GuidGenerator.Create()); + + await _menuRepository.InsertAsync(entity); + return await GetAsync(entity.Id); + } + + /// + public async Task UpdateAsync(Guid id, [FromBody] RbacMenuUpdateInputVo input) + { + var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("权限不存在"); + } + + var name = input.MenuName?.Trim(); + if (string.IsNullOrWhiteSpace(name)) + { + throw new UserFriendlyException("权限名称不能为空"); + } + + entity.MenuName = name; + entity.ParentId = input.ParentId; + entity.MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType; + entity.MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource; + entity.PermissionCode = input.PermissionCode?.Trim(); + entity.Router = input.Router?.Trim(); + entity.Component = input.Component?.Trim(); + entity.OrderNum = input.OrderNum; + entity.State = input.State; + + await _menuRepository.UpdateAsync(entity); + return await GetAsync(entity.Id); + } + + /// + public async Task DeleteAsync([FromBody] List ids) + { + var idList = ids?.Distinct().ToList() ?? new List(); + if (idList.Count == 0) + { + return; + } + + // 权限表为软删(ISoftDelete) + await _menuRepository.DeleteAsync(x => idList.Contains(x.Id)); + } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs new file mode 100644 index 0000000..7a3c28a --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs @@ -0,0 +1,201 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacRole; +using FoodLabeling.Application.Contracts.Dtos.Common; +using FoodLabeling.Application.Contracts.IServices; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Uow; +using Yi.Framework.Rbac.Domain.Entities; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace FoodLabeling.Application.Services; + +/// +/// 角色管理(食品标签-美国版对外) +/// +public class RbacRoleAppService : ApplicationService, IRbacRoleAppService +{ + private readonly ISqlSugarRepository _roleRepository; + private readonly ISqlSugarRepository _roleMenuRepository; + private readonly ISqlSugarRepository _roleDeptRepository; + private readonly ISqlSugarRepository _userRoleRepository; + + public RbacRoleAppService( + ISqlSugarRepository roleRepository, + ISqlSugarRepository roleMenuRepository, + ISqlSugarRepository roleDeptRepository, + ISqlSugarRepository userRoleRepository) + { + _roleRepository = roleRepository; + _roleMenuRepository = roleMenuRepository; + _roleDeptRepository = roleDeptRepository; + _userRoleRepository = userRoleRepository; + } + + /// + public async Task> GetListAsync([FromQuery] RbacRoleGetListInputVo input) + { + RefAsync total = 0; + + var query = _roleRepository._DbQueryable + .Where(x => x.IsDeleted == false) + .WhereIF(!string.IsNullOrWhiteSpace(input.RoleCode), x => x.RoleCode.Contains(input.RoleCode!.Trim())) + .WhereIF(!string.IsNullOrWhiteSpace(input.RoleName), x => x.RoleName.Contains(input.RoleName!.Trim())) + .WhereIF(input.State is not null, x => x.State == input.State); + + if (!string.IsNullOrWhiteSpace(input.Sorting)) + { + query = query.OrderBy(input.Sorting); + } + else + { + query = query.OrderBy(x => x.OrderNum, OrderByType.Desc); + } + + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total); + + var items = entities.Select(x => new RbacRoleGetListOutputDto + { + Id = x.Id, + RoleName = x.RoleName ?? string.Empty, + RoleCode = x.RoleCode ?? string.Empty, + Remark = x.Remark, + DataScope = (int)x.DataScope, + State = x.State, + OrderNum = x.OrderNum + }).ToList(); + + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount; + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1; + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize); + + return new PagedResultWithPageDto + { + PageIndex = pageIndex, + PageSize = pageSize, + TotalCount = total, + TotalPages = totalPages, + Items = items + }; + } + + /// + public async Task GetAsync(Guid id) + { + var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("角色不存在"); + } + + return new RbacRoleGetOutputDto + { + Id = entity.Id, + RoleName = entity.RoleName ?? string.Empty, + RoleCode = entity.RoleCode ?? string.Empty, + Remark = entity.Remark, + DataScope = (int)entity.DataScope, + State = entity.State, + OrderNum = entity.OrderNum + }; + } + + /// + public async Task CreateAsync([FromBody] RbacRoleCreateInputVo input) + { + var roleName = input.RoleName?.Trim(); + var roleCode = input.RoleCode?.Trim(); + if (string.IsNullOrWhiteSpace(roleName)) + { + throw new UserFriendlyException("角色名称不能为空"); + } + + if (string.IsNullOrWhiteSpace(roleCode)) + { + throw new UserFriendlyException("角色编码不能为空"); + } + + var isExist = await _roleRepository.IsAnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName); + if (isExist) + { + throw new UserFriendlyException("角色名称或编码已存在"); + } + + var entity = new RoleAggregateRoot + { + RoleName = roleName, + RoleCode = roleCode, + Remark = input.Remark?.Trim(), + DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope, + State = input.State, + OrderNum = input.OrderNum + }; + EntityHelper.TrySetId(entity, () => GuidGenerator.Create()); + + await _roleRepository.InsertAsync(entity); + + return await GetAsync(entity.Id); + } + + /// + public async Task UpdateAsync(Guid id, [FromBody] RbacRoleUpdateInputVo input) + { + var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false); + if (entity is null) + { + throw new UserFriendlyException("角色不存在"); + } + + var roleName = input.RoleName?.Trim(); + var roleCode = input.RoleCode?.Trim(); + if (string.IsNullOrWhiteSpace(roleName)) + { + throw new UserFriendlyException("角色名称不能为空"); + } + + if (string.IsNullOrWhiteSpace(roleCode)) + { + throw new UserFriendlyException("角色编码不能为空"); + } + + var isExist = await _roleRepository._DbQueryable + .Where(x => x.Id != entity.Id && x.IsDeleted == false) + .AnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName); + if (isExist) + { + throw new UserFriendlyException("角色名称或编码已存在"); + } + + entity.RoleName = roleName; + entity.RoleCode = roleCode; + entity.Remark = input.Remark?.Trim(); + entity.DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope; + entity.State = input.State; + entity.OrderNum = input.OrderNum; + + await _roleRepository.UpdateAsync(entity); + + return await GetAsync(entity.Id); + } + + /// + [UnitOfWork] + public async Task DeleteAsync([FromBody] List ids) + { + var idList = ids?.Distinct().ToList() ?? new List(); + if (idList.Count == 0) + { + return; + } + + await _roleMenuRepository.DeleteAsync(x => idList.Contains(x.RoleId)); + await _roleDeptRepository.DeleteAsync(x => idList.Contains(x.RoleId)); + await _userRoleRepository.DeleteAsync(x => idList.Contains(x.RoleId)); + + // 角色表为软删(ISoftDelete) + await _roleRepository.DeleteAsync(x => idList.Contains(x.Id)); + } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs new file mode 100644 index 0000000..e096e27 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs @@ -0,0 +1,102 @@ +using FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu; +using FoodLabeling.Application.Contracts.IServices; +using Microsoft.AspNetCore.Mvc; +using SqlSugar; +using Volo.Abp; +using Volo.Abp.Application.Services; +using Volo.Abp.Uow; +using Yi.Framework.Rbac.Domain.Entities; +using Yi.Framework.SqlSugarCore.Abstractions; + +namespace FoodLabeling.Application.Services; + +/// +/// 角色-权限关联(食品标签-美国版对外) +/// +public class RbacRoleMenuAppService : ApplicationService, IRbacRoleMenuAppService +{ + private readonly ISqlSugarRepository _roleRepository; + private readonly ISqlSugarRepository _menuRepository; + private readonly ISqlSugarRepository _roleMenuRepository; + + public RbacRoleMenuAppService( + ISqlSugarRepository roleRepository, + ISqlSugarRepository menuRepository, + ISqlSugarRepository roleMenuRepository) + { + _roleRepository = roleRepository; + _menuRepository = menuRepository; + _roleMenuRepository = roleMenuRepository; + } + + /// + [UnitOfWork] + public async Task SetAsync([FromBody] RbacRoleMenuSetInputVo input) + { + var role = await _roleRepository.GetSingleAsync(x => x.Id == input.RoleId && x.IsDeleted == false); + if (role is null) + { + throw new UserFriendlyException("角色不存在"); + } + + var menuIds = input.MenuIds?.Distinct().ToList() ?? new List(); + if (menuIds.Count == 0) + { + // 覆盖式:传空表示清空 + await _roleMenuRepository.DeleteAsync(x => x.RoleId == input.RoleId); + return; + } + + // 只允许分配未删除的菜单 + var existMenuIds = await _menuRepository._DbQueryable + .Where(x => x.IsDeleted == false) + .Where(x => menuIds.Contains(x.Id)) + .Select(x => x.Id) + .ToListAsync(); + + await _roleMenuRepository.DeleteAsync(x => x.RoleId == input.RoleId); + + var entities = existMenuIds.Select(menuId => new RoleMenuEntity + { + RoleId = input.RoleId, + MenuId = menuId + }).ToList(); + + if (entities.Count > 0) + { + await _roleMenuRepository.InsertRangeAsync(entities); + } + } + + /// + public async Task> GetMenuIdsAsync([FromQuery] Guid roleId) + { + return await _roleMenuRepository._DbQueryable + .Where(x => x.RoleId == roleId) + .Select(x => x.MenuId) + .ToListAsync(); + } + + /// + [UnitOfWork] + public async Task RemoveAsync([FromBody] RbacRoleMenuRemoveInputVo input) + { + var role = await _roleRepository.GetSingleAsync(x => x.Id == input.RoleId && x.IsDeleted == false); + if (role is null) + { + throw new UserFriendlyException("角色不存在"); + } + + var menuIds = input.MenuIds?.Distinct().ToList() ?? new List(); + if (menuIds.Count == 0) + { + return; + } + + await _roleMenuRepository._Db.Deleteable() + .Where(x => x.RoleId == input.RoleId) + .WhereIF(menuIds.Count > 0, x => menuIds.Contains(x.MenuId)) + .ExecuteCommandAsync(); + } +} + diff --git a/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs new file mode 100644 index 0000000..793d3e1 --- /dev/null +++ b/美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs @@ -0,0 +1,134 @@ +using SqlSugar; +using Volo.Abp.Auditing; +using Volo.Abp.Domain.Entities; +using Yi.Framework.Core.Data; + +namespace FoodLabeling.Domain.Entities; + +/// +/// 门店/位置 +/// +[SugarTable("location")] +public class LocationAggregateRoot : AggregateRoot, ISoftDelete, IAuditedObject, IOrderNum, IState +{ + public LocationAggregateRoot() + { + } + + public LocationAggregateRoot(Guid id) + { + Id = id; + } + + /// + /// 主键 + /// + [SugarColumn(IsPrimaryKey = true)] + public override Guid Id { get; protected set; } + + /// + /// 逻辑删除 + /// + public bool IsDeleted { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreationTime { get; set; } = DateTime.Now; + + /// + /// 创建者 + /// + public Guid? CreatorId { get; set; } + + /// + /// 最后修改者 + /// + public Guid? LastModifierId { get; set; } + + /// + /// 最后修改时间 + /// + public DateTime? LastModificationTime { get; set; } + + /// + /// 排序 + /// + public int OrderNum { get; set; } = 0; + + /// + /// 启用状态 + /// + public bool State { get; set; } = true; + + /// + /// Partner(原型中的 Partner 下拉) + /// + public string? Partner { get; set; } + + /// + /// Group(原型中的 Group 下拉) + /// + [SugarColumn(ColumnName = "GroupName")] + public string? GroupName { get; set; } + + /// + /// Location ID(业务编码) + /// + [SugarColumn(ColumnName = "LocationCode")] + public string LocationCode { get; set; } = string.Empty; + + /// + /// Location Name + /// + [SugarColumn(ColumnName = "LocationName")] + public string LocationName { get; set; } = string.Empty; + + /// + /// Street + /// + public string? Street { get; set; } + + /// + /// City + /// + public string? City { get; set; } + + /// + /// State(如 NY) + /// + [SugarColumn(ColumnName = "StateCode")] + public string? StateCode { get; set; } + + /// + /// Country + /// + public string? Country { get; set; } + + /// + /// Zip Code + /// + [SugarColumn(ColumnName = "ZipCode")] + public string? ZipCode { get; set; } + + /// + /// Phone + /// + public string? Phone { get; set; } + + /// + /// Email + /// + public string? Email { get; set; } + + /// + /// Latitude + /// + public decimal? Latitude { get; set; } + + /// + /// Longitude + /// + public decimal? Longitude { get; set; } +} + diff --git a/项目相关文档/门店(Location)接口对接说明.md b/项目相关文档/门店(Location)接口对接说明.md new file mode 100644 index 0000000..9f6a918 --- /dev/null +++ b/项目相关文档/门店(Location)接口对接说明.md @@ -0,0 +1,101 @@ +## 概述 + +美国版后端采用 ABP 动态接口(ConventionalControllers),宿主统一前缀为 `api/app`,Swagger 地址为: + +- `http://localhost:19001/swagger` + +门店模块的服务类为 `LocationAppService`(模块:`food-labeling-us`)。 + +> 说明:接口的最终 URL 以 Swagger 展示为准(在 Swagger 里搜索 `Location` 或 `LocationAppService` 即可)。 + +--- + +## 数据库表 + +表名:`location` + +核心字段(与原型一致): + +- Partner:`Partner` +- Group:`GroupName` +- Location ID:`LocationCode` +- Location Name:`LocationName` +- Street/City/State/Country/Zip:`Street`/`City`/`StateCode`/`Country`/`ZipCode` +- Phone/Email:`Phone`/`Email` +- GPS:`Latitude`/`Longitude` +- Active Location:`State`(1=启用,0=停用) + +--- + +## 接口 1:门店分页列表 + +### 方法签名 + +`Task> GetListAsync(LocationGetListInputVo input)` + +### 入参(LocationGetListInputVo) + +- `SkipCount`:跳过条数(分页用) +- `MaxResultCount`:每页条数(分页用) +- `Sorting`:排序字段(可选;不传默认按 CreationTime 倒序) +- `Keyword`:关键字模糊搜索(会匹配 LocationCode/LocationName/Street/City/StateCode/Country/ZipCode/Phone/Email) +- `Partner`:Partner 精确过滤(可选) +- `GroupName`:Group 精确过滤(可选) +- `State`:启用状态过滤(可选,true/false) + +### 出参(PagedResultDto) + +- `TotalCount`:总数 +- `Items`:列表 + +`LocationGetListOutputDto` 字段: + +- `Id` +- `Partner` +- `GroupName` +- `LocationCode` +- `LocationName` +- `Street` +- `City` +- `StateCode` +- `Country` +- `ZipCode` +- `Phone` +- `Email` +- `Latitude` +- `Longitude` +- `State` + +--- + +## 接口 2:新增门店 + +### 方法签名 + +`Task CreateAsync(LocationCreateInputVo input)` + +### 入参(LocationCreateInputVo) + +- `Partner`:可选 +- `GroupName`:可选 +- `LocationCode`:必填(唯一,重复会报错) +- `LocationName`:必填 +- `Street/City/StateCode/Country/ZipCode`:可选 +- `Phone/Email`:可选 +- `Latitude/Longitude`:可选(decimal) +- `State`:是否启用(默认 true) + +### 校验规则 + +- `LocationCode` 不能为空,且唯一 +- `LocationName` 不能为空 + +--- + +## Swagger 中如何找到 + +1. 启动后端宿主(`Yi.Abp.Web`),确保端口为 `19001` +2. 打开 `http://localhost:19001/swagger` +3. 在接口分组里找到 **“食品标签-美国版接口”** 或直接搜索 `Location` +4. 查看 `LocationAppService` 的 `GetListAsync` 与 `CreateAsync` + -- libgit2 0.21.4